Chromium Code Reviews| 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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 if (scroller_) { | |
| 183 gfx::Rect visible_rect = scroller_->GetVisibleRect(); | |
| 184 | |
| 185 // When the |prevent_scroll| flag is set, we use the bottom position of the | |
| 186 // visible rect. It's to keep the current visible window, in other words, | |
| 187 // not to be scrolled, when the visible rect has a blank area at the bottom. | |
| 188 // Otherwize, we use the height of the visible rect. It's to make the height | |
| 189 // smaller as possible. | |
| 190 min_height = prevent_scroll ? visible_rect.bottom() : visible_rect.height(); | |
| 191 } else { | |
| 192 min_height = fixed_height_; | |
| 193 } | |
| 194 fixed_height_ = std::max(min_height, requested_height); | |
| 195 | |
| 196 if (previous_fixed_height != fixed_height_) { | |
| 197 PreferredSizeChanged(); | |
| 198 } | |
| 199 } | |
| 200 | |
| 178 void MessageListView::SetRepositionTarget(const gfx::Rect& target) { | 201 void MessageListView::SetRepositionTarget(const gfx::Rect& target) { |
| 179 reposition_top_ = std::max(target.y(), 0); | 202 reposition_top_ = std::max(target.y(), 0); |
| 180 fixed_height_ = GetHeightForWidth(width()); | |
| 181 } | 203 } |
| 182 | 204 |
| 183 void MessageListView::ResetRepositionSession() { | 205 void MessageListView::ResetRepositionSession() { |
| 184 // Don't call DoUpdateIfPossible(), but let Layout() do the task without | 206 // Don't call DoUpdateIfPossible(), but let Layout() do the task without |
| 185 // animation. Reset will cause the change of the bubble size itself, and | 207 // animation. Reset will cause the change of the bubble size itself, and |
| 186 // animation from the old location will look weird. | 208 // animation from the old location will look weird. |
| 187 if (reposition_top_ >= 0) { | 209 if (reposition_top_ >= 0) { |
| 188 has_deferred_task_ = false; | 210 has_deferred_task_ = false; |
| 189 // cancel cause OnBoundsAnimatorDone which deletes |deleted_when_done_|. | 211 // cancel cause OnBoundsAnimatorDone which deletes |deleted_when_done_|. |
| 190 animator_.Cancel(); | 212 animator_.Cancel(); |
| 191 for (auto* view : deleting_views_) | 213 for (auto* view : deleting_views_) |
| 192 delete view; | 214 delete view; |
| 193 deleting_views_.clear(); | 215 deleting_views_.clear(); |
| 194 adding_views_.clear(); | 216 adding_views_.clear(); |
| 195 } | 217 } |
| 196 | 218 |
| 197 reposition_top_ = -1; | 219 reposition_top_ = -1; |
| 198 fixed_height_ = 0; | 220 |
| 221 UpdateFixedHeight(fixed_height_, false); | |
| 199 } | 222 } |
| 200 | 223 |
| 201 void MessageListView::ClearAllClosableNotifications( | 224 void MessageListView::ClearAllClosableNotifications( |
| 202 const gfx::Rect& visible_scroll_rect) { | 225 const gfx::Rect& visible_scroll_rect) { |
| 203 for (int i = 0; i < child_count(); ++i) { | 226 for (int i = 0; i < child_count(); ++i) { |
| 204 // Safe cast since all views in MessageListView are MessageViews. | 227 // Safe cast since all views in MessageListView are MessageViews. |
| 205 MessageView* child = (MessageView*)child_at(i); | 228 MessageView* child = (MessageView*)child_at(i); |
| 206 if (!child->visible()) | 229 if (!child->visible()) |
| 207 continue; | 230 continue; |
| 208 if (gfx::IntersectRects(child->bounds(), visible_scroll_rect).IsEmpty()) | 231 if (gfx::IntersectRects(child->bounds(), visible_scroll_rect).IsEmpty()) |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 283 return; | 306 return; |
| 284 } | 307 } |
| 285 | 308 |
| 286 int new_height = GetHeightForWidth(child_area.width() + GetInsets().width()); | 309 int new_height = GetHeightForWidth(child_area.width() + GetInsets().width()); |
| 287 SetSize(gfx::Size(child_area.width() + GetInsets().width(), new_height)); | 310 SetSize(gfx::Size(child_area.width() + GetInsets().width(), new_height)); |
| 288 | 311 |
| 289 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 312 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 290 switches::kEnableMessageCenterAlwaysScrollUpUponNotificationRemoval)) | 313 switches::kEnableMessageCenterAlwaysScrollUpUponNotificationRemoval)) |
| 291 AnimateNotificationsBelowTarget(); | 314 AnimateNotificationsBelowTarget(); |
| 292 else | 315 else |
| 293 AnimateNotificationsAboveTarget(); | 316 AnimateNotifications(); |
| 294 | 317 |
| 295 adding_views_.clear(); | 318 adding_views_.clear(); |
| 296 deleting_views_.clear(); | 319 deleting_views_.clear(); |
| 297 | 320 |
| 298 if (!animator_.IsAnimating() && GetWidget()) | 321 if (!animator_.IsAnimating() && GetWidget()) |
| 299 GetWidget()->SynthesizeMouseMoveEvent(); | 322 GetWidget()->SynthesizeMouseMoveEvent(); |
| 300 } | 323 } |
| 301 | 324 |
| 325 // TODO(yoshiki): Remove this method. It is no longer maintained. | |
| 302 void MessageListView::AnimateNotificationsBelowTarget() { | 326 void MessageListView::AnimateNotificationsBelowTarget() { |
| 303 int target_index = -1; | 327 int target_index = -1; |
| 304 int padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); | 328 int padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); |
| 305 gfx::Rect child_area = GetContentsBounds(); | 329 gfx::Rect child_area = GetContentsBounds(); |
| 306 if (reposition_top_ >= 0) { | 330 if (reposition_top_ >= 0) { |
| 307 for (int i = 0; i < child_count(); ++i) { | 331 for (int i = 0; i < child_count(); ++i) { |
| 308 views::View* child = child_at(i); | 332 views::View* child = child_at(i); |
| 309 if (child->y() >= reposition_top_) { | 333 if (child->y() >= reposition_top_) { |
| 310 // Find the target. | 334 // Find the target. |
| 311 target_index = i; | 335 target_index = i; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 355 DCHECK_EQ(heights.size(), deleting.size()); | 379 DCHECK_EQ(heights.size(), deleting.size()); |
| 356 // Calculate the vertical length between the top of message list and the top | 380 // 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 | 381 // of target. This is to shrink or expand the height of the message list |
| 358 // when the notifications above the target is changed. | 382 // when the notifications above the target is changed. |
| 359 int vertical_gap_to_target_from_top = GetInsets().top(); | 383 int vertical_gap_to_target_from_top = GetInsets().top(); |
| 360 for (int i = 0; i < target_index; i++) { | 384 for (int i = 0; i < target_index; i++) { |
| 361 if (!deleting[i]) | 385 if (!deleting[i]) |
| 362 vertical_gap_to_target_from_top += heights[i] + padding; | 386 vertical_gap_to_target_from_top += heights[i] + padding; |
| 363 } | 387 } |
| 364 | 388 |
| 365 // If the calculated length is changed from |repositon_top_|, it means that | 389 // 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. | 390 // some of items above the target are updated and their height gets longer. |
|
Eliot Courtney
2017/04/12 06:16:18
nit: gets longer => increased
yoshiki
2017/04/14 04:37:06
Done.
| |
| 367 // Adjust the vertical length above the target. | 391 // Adjust the vertical length above the target. |
| 368 fixed_height_ -= reposition_top_ - vertical_gap_to_target_from_top; | 392 if (vertical_gap_to_target_from_top > reposition_top_) { |
| 369 reposition_top_ = vertical_gap_to_target_from_top; | 393 fixed_height_ += vertical_gap_to_target_from_top - reposition_top_; |
| 394 reposition_top_ = vertical_gap_to_target_from_top; | |
| 395 } | |
| 370 | 396 |
| 371 std::vector<int> positions; | 397 std::vector<int> positions; |
| 372 positions.reserve(heights.size()); | 398 positions.reserve(heights.size()); |
| 373 // Layout the items above the target. | 399 // Layout the items above the target. |
| 374 int y = GetInsets().top(); | 400 int y = GetInsets().top(); |
| 375 for (int i = 0; i < target_index; i++) { | 401 for (int i = 0; i < target_index; i++) { |
| 376 positions.push_back(y); | 402 positions.push_back(y); |
| 377 if (!deleting[i]) | 403 if (!deleting[i]) |
| 378 y += heights[i] + padding; | 404 y += heights[i] + padding; |
| 379 } | 405 } |
| 380 DCHECK_EQ(y, reposition_top_); | 406 DCHECK_EQ(y, vertical_gap_to_target_from_top); |
| 407 DCHECK_LE(y, reposition_top_); | |
| 381 | 408 |
| 382 // Match the top with |reposition_top_|. | 409 // Match the top with |reposition_top_|. |
| 383 y = reposition_top_; | 410 y = reposition_top_; |
| 384 // Layout the target and the items below the target. | 411 // Layout the target and the items below the target. |
| 385 for (int i = target_index; i < int(heights.size()); i++) { | 412 for (int i = target_index; i < int(heights.size()); i++) { |
| 386 positions.push_back(y); | 413 positions.push_back(y); |
| 387 if (!deleting[i]) | 414 if (!deleting[i]) |
| 388 y += heights[i] + padding; | 415 y += heights[i] + padding; |
| 389 } | 416 } |
| 390 // If the target view, or any views below it expand they might exceed | 417 // If the target view, or any views below it expand they might exceed |
|
Eliot Courtney
2017/04/12 06:16:18
This comment feels like it might need updating to
yoshiki
2017/04/14 04:37:06
Done.
| |
| 391 // |fixed_height_|. Rather than letting them push out the bottom and be | 418 // |fixed_height_|. Rather than letting them push out the bottom and be |
| 392 // clipped, instead increase |fixed_height_|. | 419 // clipped, instead increase |fixed_height_|. |
| 393 fixed_height_ = std::max(fixed_height_, y - padding + GetInsets().bottom()); | 420 UpdateFixedHeight(y - padding + GetInsets().bottom(), true); |
| 394 | 421 |
| 395 return positions; | 422 return positions; |
| 396 } | 423 } |
| 397 | 424 |
| 398 void MessageListView::AnimateNotificationsAboveTarget() { | 425 void MessageListView::AnimateNotifications() { |
| 399 int target_index = -1; | 426 int target_index = -1; |
| 400 int padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); | 427 int padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); |
| 401 gfx::Rect child_area = GetContentsBounds(); | 428 gfx::Rect child_area = GetContentsBounds(); |
| 402 if (reposition_top_ >= 0) { | 429 if (reposition_top_ >= 0) { |
| 403 // Find the target item. | 430 // Find the target item. |
| 404 for (int i = 0; i < child_count(); ++i) { | 431 for (int i = 0; i < child_count(); ++i) { |
| 405 views::View* child = child_at(i); | 432 views::View* child = child_at(i); |
| 406 if (child->y() >= reposition_top_ && | 433 if (child->y() >= reposition_top_ && |
| 407 deleting_views_.find(child) == deleting_views_.end()) { | 434 deleting_views_.find(child) == deleting_views_.end()) { |
| 408 // Find the target. | 435 // Find the target. |
| 409 target_index = i; | 436 target_index = i; |
| 410 break; | 437 break; |
| 411 } | 438 } |
| 412 } | 439 } |
| 413 // If no items are below |reposition_top_|, use the last item as the target. | |
|
Eliot Courtney
2017/04/12 06:16:18
Is this no longer necessary? How come?
yoshiki
2017/04/14 04:37:06
Now animating direction changed from downward to u
| |
| 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 } | 440 } |
| 423 | 441 |
| 424 if (target_index != -1) { | 442 if (target_index != -1) { |
| 425 std::vector<int> heights; | 443 std::vector<int> heights; |
| 426 std::vector<bool> deleting; | 444 std::vector<bool> deleting; |
| 427 heights.reserve(child_count()); | 445 heights.reserve(child_count()); |
| 428 deleting.reserve(child_count()); | 446 deleting.reserve(child_count()); |
| 429 for (int i = 0; i < child_count(); i++) { | 447 for (int i = 0; i < child_count(); i++) { |
| 430 views::View* child = child_at(i); | 448 views::View* child = child_at(i); |
| 431 heights.push_back(child->GetHeightForWidth(child_area.width())); | 449 heights.push_back(child->GetHeightForWidth(child_area.width())); |
| 432 deleting.push_back(deleting_views_.find(child) != deleting_views_.end()); | 450 deleting.push_back(deleting_views_.find(child) != deleting_views_.end()); |
| 433 } | 451 } |
| 434 std::vector<int> ys = | 452 std::vector<int> ys = |
| 435 ComputeRepositionOffsets(heights, deleting, target_index, padding); | 453 ComputeRepositionOffsets(heights, deleting, target_index, padding); |
| 436 for (int i = 0; i < child_count(); ++i) { | 454 for (int i = 0; i < child_count(); ++i) { |
| 437 AnimateChild(child_at(i), ys[i], heights[i], true /* animate_on_move */); | 455 bool above_target = (i < target_index); |
| 456 AnimateChild(child_at(i), ys[i], heights[i], | |
| 457 !above_target /* animate_on_move */); | |
| 438 } | 458 } |
| 439 } else { | 459 } else { |
| 440 // Layout all the items. | 460 // Layout all the items. |
| 441 int y = GetInsets().top(); | 461 int y = GetInsets().top(); |
| 442 for (int i = 0; i < child_count(); ++i) { | 462 for (int i = 0; i < child_count(); ++i) { |
| 443 views::View* child = child_at(i); | 463 views::View* child = child_at(i); |
| 444 int height = child->GetHeightForWidth(child_area.width()); | 464 int height = child->GetHeightForWidth(child_area.width()); |
| 445 if (AnimateChild(child, y, height, true)) | 465 if (AnimateChild(child, y, height, true)) |
| 446 y += height + padding; | 466 y += height + padding; |
| 447 } | 467 } |
| 448 fixed_height_ = y - padding + GetInsets().bottom(); | 468 int new_height = y - padding + GetInsets().bottom(); |
| 469 UpdateFixedHeight(new_height, false); | |
| 449 } | 470 } |
| 450 } | 471 } |
| 451 | 472 |
| 452 bool MessageListView::AnimateChild(views::View* child, | 473 bool MessageListView::AnimateChild(views::View* child, |
| 453 int top, | 474 int top, |
| 454 int height, | 475 int height, |
| 455 bool animate_on_move) { | 476 bool animate_on_move) { |
| 456 gfx::Rect child_area = GetContentsBounds(); | 477 gfx::Rect child_area = GetContentsBounds(); |
| 457 if (adding_views_.find(child) != adding_views_.end()) { | 478 if (adding_views_.find(child) != adding_views_.end()) { |
| 458 child->SetBounds(child_area.right(), top, child_area.width(), height); | 479 child->SetBounds(child_area.right(), top, child_area.width(), height); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 495 base::TimeDelta::FromMilliseconds( | 516 base::TimeDelta::FromMilliseconds( |
| 496 kAnimateClearingNextNotificationDelayMS)); | 517 kAnimateClearingNextNotificationDelayMS)); |
| 497 } | 518 } |
| 498 } | 519 } |
| 499 | 520 |
| 500 void MessageListView::SetRepositionTargetForTest(const gfx::Rect& target_rect) { | 521 void MessageListView::SetRepositionTargetForTest(const gfx::Rect& target_rect) { |
| 501 SetRepositionTarget(target_rect); | 522 SetRepositionTarget(target_rect); |
| 502 } | 523 } |
| 503 | 524 |
| 504 } // namespace message_center | 525 } // namespace message_center |
| OLD | NEW |