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

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

Issue 2805143002: Don't shrink the message center height while open (Closed)
Patch Set: Remove unnecessary include Created 3 years, 8 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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 168
169 void MessageListView::ReorderChildLayers(ui::Layer* parent_layer) { 169 void MessageListView::ReorderChildLayers(ui::Layer* parent_layer) {
170 // Reorder children to stack the last child layer at the top. Otherwise 170 // Reorder children to stack the last child layer at the top. Otherwise
171 // upper notification may be hidden by the lower one. 171 // upper notification may be hidden by the lower one.
172 for (int i = 0; i < child_count(); ++i) { 172 for (int i = 0; i < child_count(); ++i) {
173 if (child_at(i)->layer()) 173 if (child_at(i)->layer())
174 parent_layer->StackAtBottom(child_at(i)->layer()); 174 parent_layer->StackAtBottom(child_at(i)->layer());
175 } 175 }
176 } 176 }
177 177
178 void MessageListView::UpdateFixedHeight(int requested_height,
179 bool prevent_scroll) {
180 int previous_fixed_height = fixed_height_;
181 int min_height;
182
183 // When the |prevent_scroll| flag is set, we use |fixed_height_|, which is the
184 // bottom position of the visible rect. It's to keep the current visible
185 // window, in other words, not to be scrolled, when the visible rect has a
186 // blank area at the bottom.
187 // Otherwise (in else block), we use the height of the visible rect to make
188 // the height of the message list as small as possible.
189 if (prevent_scroll) {
190 // TODO(yoshiki): Consider the case with scrolling. If the message center
191 // has scrollbar and its height is maximum, we may not need to keep the
192 // height of the list in the scroll view.
193 min_height = fixed_height_;
194 } else {
195 if (scroller_) {
196 gfx::Rect visible_rect = scroller_->GetVisibleRect();
197 min_height = visible_rect.height();
198 } else {
199 // Fallback for testing.
200 min_height = fixed_height_;
201 }
202 }
203 fixed_height_ = std::max(min_height, requested_height);
204
205 if (previous_fixed_height != fixed_height_) {
206 PreferredSizeChanged();
207 }
208 }
209
178 void MessageListView::SetRepositionTarget(const gfx::Rect& target) { 210 void MessageListView::SetRepositionTarget(const gfx::Rect& target) {
179 reposition_top_ = std::max(target.y(), 0); 211 reposition_top_ = std::max(target.y(), 0);
180 fixed_height_ = GetHeightForWidth(width()); 212 UpdateFixedHeight(GetHeightForWidth(width()), false);
181 } 213 }
182 214
183 void MessageListView::ResetRepositionSession() { 215 void MessageListView::ResetRepositionSession() {
184 // Don't call DoUpdateIfPossible(), but let Layout() do the task without 216 // Don't call DoUpdateIfPossible(), but let Layout() do the task without
185 // animation. Reset will cause the change of the bubble size itself, and 217 // animation. Reset will cause the change of the bubble size itself, and
186 // animation from the old location will look weird. 218 // animation from the old location will look weird.
187 if (reposition_top_ >= 0) { 219 if (reposition_top_ >= 0) {
188 has_deferred_task_ = false; 220 has_deferred_task_ = false;
189 // cancel cause OnBoundsAnimatorDone which deletes |deleted_when_done_|. 221 // cancel cause OnBoundsAnimatorDone which deletes |deleted_when_done_|.
190 animator_.Cancel(); 222 animator_.Cancel();
191 for (auto* view : deleting_views_) 223 for (auto* view : deleting_views_)
192 delete view; 224 delete view;
193 deleting_views_.clear(); 225 deleting_views_.clear();
194 adding_views_.clear(); 226 adding_views_.clear();
195 } 227 }
196 228
197 reposition_top_ = -1; 229 reposition_top_ = -1;
198 fixed_height_ = 0; 230
231 UpdateFixedHeight(fixed_height_, false);
199 } 232 }
200 233
201 void MessageListView::ClearAllClosableNotifications( 234 void MessageListView::ClearAllClosableNotifications(
202 const gfx::Rect& visible_scroll_rect) { 235 const gfx::Rect& visible_scroll_rect) {
203 for (int i = 0; i < child_count(); ++i) { 236 for (int i = 0; i < child_count(); ++i) {
204 // Safe cast since all views in MessageListView are MessageViews. 237 // Safe cast since all views in MessageListView are MessageViews.
205 MessageView* child = (MessageView*)child_at(i); 238 MessageView* child = (MessageView*)child_at(i);
206 if (!child->visible()) 239 if (!child->visible())
207 continue; 240 continue;
208 if (gfx::IntersectRects(child->bounds(), visible_scroll_rect).IsEmpty()) 241 if (gfx::IntersectRects(child->bounds(), visible_scroll_rect).IsEmpty())
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 return; 316 return;
284 } 317 }
285 318
286 int new_height = GetHeightForWidth(child_area.width() + GetInsets().width()); 319 int new_height = GetHeightForWidth(child_area.width() + GetInsets().width());
287 SetSize(gfx::Size(child_area.width() + GetInsets().width(), new_height)); 320 SetSize(gfx::Size(child_area.width() + GetInsets().width(), new_height));
288 321
289 if (base::CommandLine::ForCurrentProcess()->HasSwitch( 322 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
290 switches::kEnableMessageCenterAlwaysScrollUpUponNotificationRemoval)) 323 switches::kEnableMessageCenterAlwaysScrollUpUponNotificationRemoval))
291 AnimateNotificationsBelowTarget(); 324 AnimateNotificationsBelowTarget();
292 else 325 else
293 AnimateNotificationsAboveTarget(); 326 AnimateNotifications();
294 327
295 adding_views_.clear(); 328 adding_views_.clear();
296 deleting_views_.clear(); 329 deleting_views_.clear();
297 330
298 if (!animator_.IsAnimating() && GetWidget()) 331 if (!animator_.IsAnimating() && GetWidget())
299 GetWidget()->SynthesizeMouseMoveEvent(); 332 GetWidget()->SynthesizeMouseMoveEvent();
300 } 333 }
301 334
335 // TODO(yoshiki): Remove this method. It is no longer maintained.
302 void MessageListView::AnimateNotificationsBelowTarget() { 336 void MessageListView::AnimateNotificationsBelowTarget() {
303 int target_index = -1; 337 int target_index = -1;
304 int padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); 338 int padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom();
305 gfx::Rect child_area = GetContentsBounds(); 339 gfx::Rect child_area = GetContentsBounds();
306 if (reposition_top_ >= 0) { 340 if (reposition_top_ >= 0) {
307 for (int i = 0; i < child_count(); ++i) { 341 for (int i = 0; i < child_count(); ++i) {
308 views::View* child = child_at(i); 342 views::View* child = child_at(i);
309 if (child->y() >= reposition_top_) { 343 if (child->y() >= reposition_top_) {
310 // Find the target. 344 // Find the target.
311 target_index = i; 345 target_index = i;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 DCHECK_EQ(heights.size(), deleting.size()); 389 DCHECK_EQ(heights.size(), deleting.size());
356 // Calculate the vertical length between the top of message list and the top 390 // 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 391 // of target. This is to shrink or expand the height of the message list
358 // when the notifications above the target is changed. 392 // when the notifications above the target is changed.
359 int vertical_gap_to_target_from_top = GetInsets().top(); 393 int vertical_gap_to_target_from_top = GetInsets().top();
360 for (int i = 0; i < target_index; i++) { 394 for (int i = 0; i < target_index; i++) {
361 if (!deleting[i]) 395 if (!deleting[i])
362 vertical_gap_to_target_from_top += heights[i] + padding; 396 vertical_gap_to_target_from_top += heights[i] + padding;
363 } 397 }
364 398
365 // If the calculated length is changed from |repositon_top_|, it means that 399 // If the calculated length is expanded from |repositon_top_|, it means that
366 // some of items above the target are updated and their height are changed. 400 // some of items above the target are updated and their height increased.
367 // Adjust the vertical length above the target. 401 // Adjust the vertical length above the target.
368 fixed_height_ -= reposition_top_ - vertical_gap_to_target_from_top; 402 if (vertical_gap_to_target_from_top > reposition_top_) {
369 reposition_top_ = vertical_gap_to_target_from_top; 403 fixed_height_ += vertical_gap_to_target_from_top - reposition_top_;
404 reposition_top_ = vertical_gap_to_target_from_top;
405 }
406
407 // TODO(yoshiki): Scroll the parent container to keep the physical position
408 // of the target notification when the scrolling is caused by a size change
409 // of notification above.
370 410
371 std::vector<int> positions; 411 std::vector<int> positions;
372 positions.reserve(heights.size()); 412 positions.reserve(heights.size());
373 // Layout the items above the target. 413 // Layout the items above the target.
374 int y = GetInsets().top(); 414 int y = GetInsets().top();
375 for (int i = 0; i < target_index; i++) { 415 for (int i = 0; i < target_index; i++) {
376 positions.push_back(y); 416 positions.push_back(y);
377 if (!deleting[i]) 417 if (!deleting[i])
378 y += heights[i] + padding; 418 y += heights[i] + padding;
379 } 419 }
380 DCHECK_EQ(y, reposition_top_); 420 DCHECK_EQ(y, vertical_gap_to_target_from_top);
421 DCHECK_LE(y, reposition_top_);
381 422
382 // Match the top with |reposition_top_|. 423 // Match the top with |reposition_top_|.
383 y = reposition_top_; 424 y = reposition_top_;
384 // Layout the target and the items below the target. 425 // Layout the target and the items below the target.
385 for (int i = target_index; i < int(heights.size()); i++) { 426 for (int i = target_index; i < int(heights.size()); i++) {
386 positions.push_back(y); 427 positions.push_back(y);
387 if (!deleting[i]) 428 if (!deleting[i])
388 y += heights[i] + padding; 429 y += heights[i] + padding;
389 } 430 }
390 // If the target view, or any views below it expand they might exceed 431
391 // |fixed_height_|. Rather than letting them push out the bottom and be 432 // Update the fixed height. |requested_height| is the height to have all
392 // clipped, instead increase |fixed_height_|. 433 // notifications in the list and to keep the vertical position of the target
393 fixed_height_ = std::max(fixed_height_, y - padding + GetInsets().bottom()); 434 // notification. It may not just a total of all the notification heights if
435 // the target exists.
436 int requested_height = y - padding + GetInsets().bottom();
437 UpdateFixedHeight(requested_height, true);
394 438
395 return positions; 439 return positions;
396 } 440 }
397 441
398 void MessageListView::AnimateNotificationsAboveTarget() { 442 void MessageListView::AnimateNotifications() {
399 int target_index = -1; 443 int target_index = -1;
400 int padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); 444 int padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom();
401 gfx::Rect child_area = GetContentsBounds(); 445 gfx::Rect child_area = GetContentsBounds();
402 if (reposition_top_ >= 0) { 446 if (reposition_top_ >= 0) {
403 // Find the target item. 447 // Find the target item.
404 for (int i = 0; i < child_count(); ++i) { 448 for (int i = 0; i < child_count(); ++i) {
405 views::View* child = child_at(i); 449 views::View* child = child_at(i);
406 if (child->y() >= reposition_top_ && 450 if (child->y() >= reposition_top_ &&
407 deleting_views_.find(child) == deleting_views_.end()) { 451 deleting_views_.find(child) == deleting_views_.end()) {
408 // Find the target. 452 // Find the target.
409 target_index = i; 453 target_index = i;
410 break; 454 break;
411 } 455 }
412 } 456 }
413 // If no items are below |reposition_top_|, use the last item as the target.
414 if (target_index == -1) {
415 target_index = child_count() - 1;
416 for (; target_index != -1; target_index--) {
417 views::View* target_view = child_at(target_index);
418 if (deleting_views_.find(target_view) == deleting_views_.end())
419 break;
420 }
421 }
422 } 457 }
423 458
424 if (target_index != -1) { 459 if (target_index != -1) {
425 std::vector<int> heights; 460 std::vector<int> heights;
426 std::vector<bool> deleting; 461 std::vector<bool> deleting;
427 heights.reserve(child_count()); 462 heights.reserve(child_count());
428 deleting.reserve(child_count()); 463 deleting.reserve(child_count());
429 for (int i = 0; i < child_count(); i++) { 464 for (int i = 0; i < child_count(); i++) {
430 views::View* child = child_at(i); 465 views::View* child = child_at(i);
431 heights.push_back(child->GetHeightForWidth(child_area.width())); 466 heights.push_back(child->GetHeightForWidth(child_area.width()));
432 deleting.push_back(deleting_views_.find(child) != deleting_views_.end()); 467 deleting.push_back(deleting_views_.find(child) != deleting_views_.end());
433 } 468 }
434 std::vector<int> ys = 469 std::vector<int> ys =
435 ComputeRepositionOffsets(heights, deleting, target_index, padding); 470 ComputeRepositionOffsets(heights, deleting, target_index, padding);
436 for (int i = 0; i < child_count(); ++i) { 471 for (int i = 0; i < child_count(); ++i) {
437 AnimateChild(child_at(i), ys[i], heights[i], true /* animate_on_move */); 472 bool above_target = (i < target_index);
473 AnimateChild(child_at(i), ys[i], heights[i],
474 !above_target /* animate_on_move */);
438 } 475 }
439 } else { 476 } else {
440 // Layout all the items. 477 // Layout all the items.
441 int y = GetInsets().top(); 478 int y = GetInsets().top();
442 for (int i = 0; i < child_count(); ++i) { 479 for (int i = 0; i < child_count(); ++i) {
443 views::View* child = child_at(i); 480 views::View* child = child_at(i);
444 int height = child->GetHeightForWidth(child_area.width()); 481 int height = child->GetHeightForWidth(child_area.width());
445 if (AnimateChild(child, y, height, true)) 482 if (AnimateChild(child, y, height, true))
446 y += height + padding; 483 y += height + padding;
447 } 484 }
448 fixed_height_ = y - padding + GetInsets().bottom(); 485 int new_height = y - padding + GetInsets().bottom();
486 UpdateFixedHeight(new_height, false);
449 } 487 }
450 } 488 }
451 489
452 bool MessageListView::AnimateChild(views::View* child, 490 bool MessageListView::AnimateChild(views::View* child,
453 int top, 491 int top,
454 int height, 492 int height,
455 bool animate_on_move) { 493 bool animate_on_move) {
456 gfx::Rect child_area = GetContentsBounds(); 494 gfx::Rect child_area = GetContentsBounds();
457 if (adding_views_.find(child) != adding_views_.end()) { 495 if (adding_views_.find(child) != adding_views_.end()) {
458 child->SetBounds(child_area.right(), top, child_area.width(), height); 496 child->SetBounds(child_area.right(), top, child_area.width(), height);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 base::TimeDelta::FromMilliseconds( 533 base::TimeDelta::FromMilliseconds(
496 kAnimateClearingNextNotificationDelayMS)); 534 kAnimateClearingNextNotificationDelayMS));
497 } 535 }
498 } 536 }
499 537
500 void MessageListView::SetRepositionTargetForTest(const gfx::Rect& target_rect) { 538 void MessageListView::SetRepositionTargetForTest(const gfx::Rect& target_rect) {
501 SetRepositionTarget(target_rect); 539 SetRepositionTarget(target_rect);
502 } 540 }
503 541
504 } // namespace message_center 542 } // 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