| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ash/launcher/launcher_view.h" | 5 #include "ash/launcher/launcher_view.h" |
| 6 | 6 |
| 7 #include "ash/launcher/launcher_button.h" | 7 #include "ash/launcher/launcher_button.h" |
| 8 #include "ash/launcher/launcher_delegate.h" | 8 #include "ash/launcher/launcher_delegate.h" |
| 9 #include "ash/launcher/launcher_icon_observer.h" | |
| 10 #include "ash/launcher/launcher_model.h" | 9 #include "ash/launcher/launcher_model.h" |
| 11 #include "ash/launcher/tabbed_launcher_button.h" | 10 #include "ash/launcher/tabbed_launcher_button.h" |
| 12 #include "ash/shell.h" | 11 #include "ash/shell.h" |
| 13 #include "ash/shell_delegate.h" | 12 #include "ash/shell_delegate.h" |
| 14 #include "base/auto_reset.h" | 13 #include "base/auto_reset.h" |
| 15 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 16 #include "grit/ash_strings.h" | 15 #include "grit/ash_strings.h" |
| 17 #include "grit/ui_resources.h" | 16 #include "grit/ui_resources.h" |
| 18 #include "ui/aura/window.h" | 17 #include "ui/aura/window.h" |
| 19 #include "ui/base/animation/animation.h" | 18 #include "ui/base/animation/animation.h" |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 return NULL; | 248 return NULL; |
| 250 | 249 |
| 251 return static_cast<LauncherButton*>( | 250 return static_cast<LauncherButton*>( |
| 252 launcher_view_->view_model_->view_at(index)); | 251 launcher_view_->view_model_->view_at(index)); |
| 253 } | 252 } |
| 254 | 253 |
| 255 LauncherView::LauncherView(LauncherModel* model, LauncherDelegate* delegate) | 254 LauncherView::LauncherView(LauncherModel* model, LauncherDelegate* delegate) |
| 256 : model_(model), | 255 : model_(model), |
| 257 delegate_(delegate), | 256 delegate_(delegate), |
| 258 view_model_(new views::ViewModel), | 257 view_model_(new views::ViewModel), |
| 259 last_visible_index_(-1), | |
| 260 overflow_button_(NULL), | 258 overflow_button_(NULL), |
| 261 dragging_(NULL), | 259 dragging_(NULL), |
| 262 drag_view_(NULL), | 260 drag_view_(NULL), |
| 263 drag_offset_(0), | 261 drag_offset_(0), |
| 264 start_drag_index_(-1), | 262 start_drag_index_(-1), |
| 265 context_menu_id_(0) { | 263 context_menu_id_(0) { |
| 266 DCHECK(model_); | 264 DCHECK(model_); |
| 267 bounds_animator_.reset(new views::BoundsAnimator(this)); | 265 bounds_animator_.reset(new views::BoundsAnimator(this)); |
| 268 set_context_menu_controller(this); | 266 set_context_menu_controller(this); |
| 269 focus_search_.reset(new LauncherFocusSearch(view_model_.get())); | 267 focus_search_.reset(new LauncherFocusSearch(view_model_.get())); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 300 l10n_util::GetStringUTF16(IDS_AURA_LAUNCHER_OVERFLOW_NAME)); | 298 l10n_util::GetStringUTF16(IDS_AURA_LAUNCHER_OVERFLOW_NAME)); |
| 301 overflow_button_->set_context_menu_controller(this); | 299 overflow_button_->set_context_menu_controller(this); |
| 302 ConfigureChildView(overflow_button_); | 300 ConfigureChildView(overflow_button_); |
| 303 AddChildView(overflow_button_); | 301 AddChildView(overflow_button_); |
| 304 | 302 |
| 305 // We'll layout when our bounds change. | 303 // We'll layout when our bounds change. |
| 306 } | 304 } |
| 307 | 305 |
| 308 gfx::Rect LauncherView::GetIdealBoundsOfItemIcon(LauncherID id) { | 306 gfx::Rect LauncherView::GetIdealBoundsOfItemIcon(LauncherID id) { |
| 309 int index = model_->ItemIndexByID(id); | 307 int index = model_->ItemIndexByID(id); |
| 310 if (index == -1 || index > last_visible_index_) | 308 if (index == -1 || !view_model_->view_at(index)->visible()) |
| 311 return gfx::Rect(); | 309 return gfx::Rect(); |
| 312 const gfx::Rect& ideal_bounds(view_model_->ideal_bounds(index)); | 310 const gfx::Rect& ideal_bounds(view_model_->ideal_bounds(index)); |
| 313 DCHECK_NE(TYPE_APP_LIST, model_->items()[index].type); | 311 DCHECK_NE(TYPE_APP_LIST, model_->items()[index].type); |
| 314 LauncherButton* button = | 312 LauncherButton* button = |
| 315 static_cast<LauncherButton*>(view_model_->view_at(index)); | 313 static_cast<LauncherButton*>(view_model_->view_at(index)); |
| 316 gfx::Rect icon_bounds = button->GetIconBounds(); | 314 gfx::Rect icon_bounds = button->GetIconBounds(); |
| 317 return gfx::Rect(ideal_bounds.x() + icon_bounds.x(), | 315 return gfx::Rect(ideal_bounds.x() + icon_bounds.x(), |
| 318 ideal_bounds.y() + icon_bounds.y(), | 316 ideal_bounds.y() + icon_bounds.y(), |
| 319 icon_bounds.width(), icon_bounds.height()); | 317 icon_bounds.width(), icon_bounds.height()); |
| 320 } | 318 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 int x = kLeadingInset; | 357 int x = kLeadingInset; |
| 360 for (int i = 0; i < view_model_->view_size(); ++i) { | 358 for (int i = 0; i < view_model_->view_size(); ++i) { |
| 361 gfx::Size pref(kButtonWidth, kButtonHeight); | 359 gfx::Size pref(kButtonWidth, kButtonHeight); |
| 362 view_model_->set_ideal_bounds(i, gfx::Rect( | 360 view_model_->set_ideal_bounds(i, gfx::Rect( |
| 363 x, (kLauncherPreferredHeight - pref.height()) / 2, pref.width(), | 361 x, (kLauncherPreferredHeight - pref.height()) / 2, pref.width(), |
| 364 pref.height())); | 362 pref.height())); |
| 365 x += pref.width() + kButtonSpacing; | 363 x += pref.width() + kButtonSpacing; |
| 366 } | 364 } |
| 367 | 365 |
| 368 bounds->overflow_bounds.set_size(gfx::Size(kButtonWidth, kButtonHeight)); | 366 bounds->overflow_bounds.set_size(gfx::Size(kButtonWidth, kButtonHeight)); |
| 369 last_visible_index_ = DetermineLastVisibleIndex( | 367 int last_visible_index = DetermineLastVisibleIndex( |
| 370 available_width - kLeadingInset - bounds->overflow_bounds.width() - | 368 available_width - kLeadingInset - bounds->overflow_bounds.width() - |
| 371 kButtonSpacing - kButtonWidth); | 369 kButtonSpacing - kButtonWidth); |
| 372 bool show_overflow = | 370 bool show_overflow = |
| 373 (last_visible_index_ + 1 != view_model_->view_size()); | 371 (last_visible_index + 1 != view_model_->view_size()); |
| 374 int app_list_index = view_model_->view_size() - 1; | 372 int app_list_index = view_model_->view_size() - 1; |
| 375 if (overflow_button_->visible() != show_overflow) { | 373 if (overflow_button_->visible() != show_overflow) { |
| 376 // Only change visibility of the views if the visibility of the overflow | 374 // Only change visibility of the views if the visibility of the overflow |
| 377 // button changes. Otherwise we'll effect the insertion animation, which | 375 // button changes. Otherwise we'll effect the insertion animation, which |
| 378 // changes the visibility. | 376 // changes the visibility. |
| 379 for (int i = 0; i <= last_visible_index_; ++i) | 377 for (int i = 0; i <= last_visible_index; ++i) |
| 380 view_model_->view_at(i)->SetVisible(true); | 378 view_model_->view_at(i)->SetVisible(true); |
| 381 for (int i = last_visible_index_ + 1; i < view_model_->view_size(); ++i) { | 379 for (int i = last_visible_index + 1; i < view_model_->view_size(); ++i) { |
| 382 if (i != app_list_index) | 380 if (i != app_list_index) |
| 383 view_model_->view_at(i)->SetVisible(false); | 381 view_model_->view_at(i)->SetVisible(false); |
| 384 } | 382 } |
| 385 } | 383 } |
| 386 overflow_button_->SetVisible(show_overflow); | 384 overflow_button_->SetVisible(show_overflow); |
| 387 if (show_overflow) { | 385 if (show_overflow) { |
| 388 DCHECK_NE(0, view_model_->view_size()); | 386 DCHECK_NE(0, view_model_->view_size()); |
| 389 // We always want the app list visible. | 387 // We always want the app list visible. |
| 390 gfx::Rect app_list_bounds = view_model_->ideal_bounds(app_list_index); | 388 gfx::Rect app_list_bounds = view_model_->ideal_bounds(app_list_index); |
| 391 x = last_visible_index_ == -1 ? | 389 x = last_visible_index == -1 ? |
| 392 kLeadingInset : view_model_->ideal_bounds(last_visible_index_).right(); | 390 kLeadingInset : view_model_->ideal_bounds(last_visible_index).right(); |
| 393 app_list_bounds.set_x(x); | 391 app_list_bounds.set_x(x); |
| 394 view_model_->set_ideal_bounds(app_list_index, app_list_bounds); | 392 view_model_->set_ideal_bounds(app_list_index, app_list_bounds); |
| 395 x = app_list_bounds.right() + kButtonSpacing; | 393 x = app_list_bounds.right() + kButtonSpacing; |
| 396 bounds->overflow_bounds.set_x(x); | 394 bounds->overflow_bounds.set_x(x); |
| 397 bounds->overflow_bounds.set_y( | 395 bounds->overflow_bounds.set_y( |
| 398 (kLauncherPreferredHeight - bounds->overflow_bounds.height()) / 2); | 396 (kLauncherPreferredHeight - bounds->overflow_bounds.height()) / 2); |
| 399 } | 397 } |
| 400 } | 398 } |
| 401 | 399 |
| 402 int LauncherView::DetermineLastVisibleIndex(int max_x) { | 400 int LauncherView::DetermineLastVisibleIndex(int max_x) { |
| 403 int index = view_model_->view_size() - 1; | 401 int index = view_model_->view_size() - 1; |
| 404 while (index >= 0 && view_model_->ideal_bounds(index).right() > max_x) | 402 while (index >= 0 && view_model_->ideal_bounds(index).right() > max_x) |
| 405 index--; | 403 index--; |
| 406 return index; | 404 return index; |
| 407 } | 405 } |
| 408 | 406 |
| 409 void LauncherView::AddIconObserver(LauncherIconObserver* observer) { | |
| 410 observers_.AddObserver(observer); | |
| 411 } | |
| 412 | |
| 413 void LauncherView::RemoveIconObserver(LauncherIconObserver* observer) { | |
| 414 observers_.RemoveObserver(observer); | |
| 415 } | |
| 416 | |
| 417 void LauncherView::AnimateToIdealBounds() { | 407 void LauncherView::AnimateToIdealBounds() { |
| 418 IdealBounds ideal_bounds; | 408 IdealBounds ideal_bounds; |
| 419 CalculateIdealBounds(&ideal_bounds); | 409 CalculateIdealBounds(&ideal_bounds); |
| 420 for (int i = 0; i < view_model_->view_size(); ++i) { | 410 for (int i = 0; i < view_model_->view_size(); ++i) { |
| 421 bounds_animator_->AnimateViewTo(view_model_->view_at(i), | 411 bounds_animator_->AnimateViewTo(view_model_->view_at(i), |
| 422 view_model_->ideal_bounds(i)); | 412 view_model_->ideal_bounds(i)); |
| 423 } | 413 } |
| 424 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); | 414 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); |
| 425 } | 415 } |
| 426 | 416 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 return; | 534 return; |
| 545 | 535 |
| 546 // Remove the observer while we mutate the model so that we don't attempt to | 536 // Remove the observer while we mutate the model so that we don't attempt to |
| 547 // cancel the drag. | 537 // cancel the drag. |
| 548 model_->RemoveObserver(this); | 538 model_->RemoveObserver(this); |
| 549 model_->Move(current_index, target_index); | 539 model_->Move(current_index, target_index); |
| 550 model_->AddObserver(this); | 540 model_->AddObserver(this); |
| 551 view_model_->Move(current_index, target_index); | 541 view_model_->Move(current_index, target_index); |
| 552 AnimateToIdealBounds(); | 542 AnimateToIdealBounds(); |
| 553 bounds_animator_->StopAnimatingView(drag_view_); | 543 bounds_animator_->StopAnimatingView(drag_view_); |
| 554 | |
| 555 FOR_EACH_OBSERVER(LauncherIconObserver, observers_, | |
| 556 OnLauncherIconPositionsChanged()); | |
| 557 } | 544 } |
| 558 | 545 |
| 559 bool LauncherView::SameDragType(LauncherItemType typea, | 546 bool LauncherView::SameDragType(LauncherItemType typea, |
| 560 LauncherItemType typeb) const { | 547 LauncherItemType typeb) const { |
| 561 switch(typea) { | 548 switch(typea) { |
| 562 case TYPE_TABBED: | 549 case TYPE_TABBED: |
| 563 case TYPE_APP_PANEL: | 550 case TYPE_APP_PANEL: |
| 564 return (typeb == TYPE_TABBED || typeb == TYPE_APP_PANEL); | 551 return (typeb == TYPE_TABBED || typeb == TYPE_APP_PANEL); |
| 565 case TYPE_APP_SHORTCUT: | 552 case TYPE_APP_SHORTCUT: |
| 566 case TYPE_APP_LIST: | 553 case TYPE_APP_LIST: |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 // Should always have two items. | 655 // Should always have two items. |
| 669 return gfx::Size(view_model_->ideal_bounds(1).right() + kLeadingInset, | 656 return gfx::Size(view_model_->ideal_bounds(1).right() + kLeadingInset, |
| 670 kLauncherPreferredHeight); | 657 kLauncherPreferredHeight); |
| 671 } | 658 } |
| 672 return gfx::Size(kButtonWidth * 2 + kLeadingInset * 2, | 659 return gfx::Size(kButtonWidth * 2 + kLeadingInset * 2, |
| 673 kLauncherPreferredHeight); | 660 kLauncherPreferredHeight); |
| 674 } | 661 } |
| 675 | 662 |
| 676 void LauncherView::OnBoundsChanged(const gfx::Rect& previous_bounds) { | 663 void LauncherView::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
| 677 LayoutToIdealBounds(); | 664 LayoutToIdealBounds(); |
| 678 FOR_EACH_OBSERVER(LauncherIconObserver, observers_, | |
| 679 OnLauncherIconPositionsChanged()); | |
| 680 } | 665 } |
| 681 | 666 |
| 682 views::FocusTraversable* LauncherView::GetPaneFocusTraversable() { | 667 views::FocusTraversable* LauncherView::GetPaneFocusTraversable() { |
| 683 return this; | 668 return this; |
| 684 } | 669 } |
| 685 | 670 |
| 686 void LauncherView::LauncherItemAdded(int model_index) { | 671 void LauncherView::LauncherItemAdded(int model_index) { |
| 687 CancelDrag(NULL); | 672 CancelDrag(NULL); |
| 688 | 673 |
| 689 views::View* view = CreateViewForItem(model_->items()[model_index]); | 674 views::View* view = CreateViewForItem(model_->items()[model_index]); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 701 view->SetBoundsRect(view_model_->ideal_bounds(model_index)); | 686 view->SetBoundsRect(view_model_->ideal_bounds(model_index)); |
| 702 | 687 |
| 703 // The first animation moves all the views to their target position. |view| is | 688 // The first animation moves all the views to their target position. |view| is |
| 704 // hidden, so it visually appears as though we are providing space for | 689 // hidden, so it visually appears as though we are providing space for |
| 705 // it. When done we'll fade the view in. | 690 // it. When done we'll fade the view in. |
| 706 AnimateToIdealBounds(); | 691 AnimateToIdealBounds(); |
| 707 if (!overflow_button_->visible()) { | 692 if (!overflow_button_->visible()) { |
| 708 bounds_animator_->SetAnimationDelegate( | 693 bounds_animator_->SetAnimationDelegate( |
| 709 view, new StartFadeAnimationDelegate(this, view), true); | 694 view, new StartFadeAnimationDelegate(this, view), true); |
| 710 } | 695 } |
| 711 | |
| 712 FOR_EACH_OBSERVER(LauncherIconObserver, observers_, | |
| 713 OnLauncherIconPositionsChanged()); | |
| 714 } | 696 } |
| 715 | 697 |
| 716 void LauncherView::LauncherItemRemoved(int model_index, LauncherID id) { | 698 void LauncherView::LauncherItemRemoved(int model_index, LauncherID id) { |
| 717 #if !defined(OS_MACOSX) | 699 #if !defined(OS_MACOSX) |
| 718 if (id == context_menu_id_) | 700 if (id == context_menu_id_) |
| 719 launcher_menu_runner_.reset(); | 701 launcher_menu_runner_.reset(); |
| 720 #endif | 702 #endif |
| 721 views::View* view = view_model_->view_at(model_index); | 703 views::View* view = view_model_->view_at(model_index); |
| 722 CancelDrag(view); | 704 CancelDrag(view); |
| 723 view_model_->Remove(model_index); | 705 view_model_->Remove(model_index); |
| 724 // The first animation fades out the view. When done we'll animate the rest of | 706 // The first animation fades out the view. When done we'll animate the rest of |
| 725 // the views to their target location. | 707 // the views to their target location. |
| 726 bounds_animator_->AnimateViewTo(view, view->bounds()); | 708 bounds_animator_->AnimateViewTo(view, view->bounds()); |
| 727 bounds_animator_->SetAnimationDelegate( | 709 bounds_animator_->SetAnimationDelegate( |
| 728 view, new FadeOutAnimationDelegate(this, view), true); | 710 view, new FadeOutAnimationDelegate(this, view), true); |
| 729 | |
| 730 // The animation will eventually update the ideal bounds, but we want to | |
| 731 // force an update immediately so we can notify launcher icon observers. | |
| 732 IdealBounds ideal_bounds; | |
| 733 CalculateIdealBounds(&ideal_bounds); | |
| 734 | |
| 735 FOR_EACH_OBSERVER(LauncherIconObserver, observers_, | |
| 736 OnLauncherIconPositionsChanged()); | |
| 737 } | 711 } |
| 738 | 712 |
| 739 void LauncherView::LauncherItemChanged(int model_index, | 713 void LauncherView::LauncherItemChanged(int model_index, |
| 740 const ash::LauncherItem& old_item) { | 714 const ash::LauncherItem& old_item) { |
| 741 const LauncherItem& item(model_->items()[model_index]); | 715 const LauncherItem& item(model_->items()[model_index]); |
| 742 if (old_item.type != item.type) { | 716 if (old_item.type != item.type) { |
| 743 // Type changed, swap the views. | 717 // Type changed, swap the views. |
| 744 scoped_ptr<views::View> old_view(view_model_->view_at(model_index)); | 718 scoped_ptr<views::View> old_view(view_model_->view_at(model_index)); |
| 745 bounds_animator_->StopAnimatingView(old_view.get()); | 719 bounds_animator_->StopAnimatingView(old_view.get()); |
| 746 CancelDrag(old_view.get()); | 720 CancelDrag(old_view.get()); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 776 } | 750 } |
| 777 | 751 |
| 778 default: | 752 default: |
| 779 break; | 753 break; |
| 780 } | 754 } |
| 781 } | 755 } |
| 782 | 756 |
| 783 void LauncherView::LauncherItemMoved(int start_index, int target_index) { | 757 void LauncherView::LauncherItemMoved(int start_index, int target_index) { |
| 784 view_model_->Move(start_index, target_index); | 758 view_model_->Move(start_index, target_index); |
| 785 AnimateToIdealBounds(); | 759 AnimateToIdealBounds(); |
| 786 FOR_EACH_OBSERVER(LauncherIconObserver, observers_, | |
| 787 OnLauncherIconPositionsChanged()); | |
| 788 } | 760 } |
| 789 | 761 |
| 790 void LauncherView::LauncherItemWillChange(int index) { | 762 void LauncherView::LauncherItemWillChange(int index) { |
| 791 const LauncherItem& item(model_->items()[index]); | 763 const LauncherItem& item(model_->items()[index]); |
| 792 views::View* view = view_model_->view_at(index); | 764 views::View* view = view_model_->view_at(index); |
| 793 if (item.type == TYPE_TABBED) | 765 if (item.type == TYPE_TABBED) |
| 794 static_cast<TabbedLauncherButton*>(view)->PrepareForImageChange(); | 766 static_cast<TabbedLauncherButton*>(view)->PrepareForImageChange(); |
| 795 } | 767 } |
| 796 | 768 |
| 797 void LauncherView::MousePressedOnButton(views::View* view, | 769 void LauncherView::MousePressedOnButton(views::View* view, |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 source->GetWidget(), NULL, gfx::Rect(point, gfx::Size()), | 888 source->GetWidget(), NULL, gfx::Rect(point, gfx::Size()), |
| 917 views::MenuItemView::TOPLEFT, 0) == views::MenuRunner::MENU_DELETED) | 889 views::MenuItemView::TOPLEFT, 0) == views::MenuRunner::MENU_DELETED) |
| 918 return; | 890 return; |
| 919 | 891 |
| 920 Shell::GetInstance()->UpdateShelfVisibility(); | 892 Shell::GetInstance()->UpdateShelfVisibility(); |
| 921 #endif | 893 #endif |
| 922 } | 894 } |
| 923 | 895 |
| 924 } // namespace internal | 896 } // namespace internal |
| 925 } // namespace ash | 897 } // namespace ash |
| OLD | NEW |