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/shelf/shelf_view.h" | 5 #include "ash/shelf/shelf_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "ash/ash_constants.h" | 9 #include "ash/ash_constants.h" |
10 #include "ash/ash_switches.h" | 10 #include "ash/ash_switches.h" |
11 #include "ash/drag_drop/drag_image_view.h" | 11 #include "ash/drag_drop/drag_image_view.h" |
12 #include "ash/metrics/user_metrics_recorder.h" | 12 #include "ash/metrics/user_metrics_recorder.h" |
13 #include "ash/root_window_controller.h" | 13 #include "ash/root_window_controller.h" |
14 #include "ash/scoped_target_root_window.h" | 14 #include "ash/scoped_target_root_window.h" |
| 15 #include "ash/shelf/alternate_app_list_button.h" |
15 #include "ash/shelf/app_list_button.h" | 16 #include "ash/shelf/app_list_button.h" |
16 #include "ash/shelf/overflow_bubble.h" | 17 #include "ash/shelf/overflow_bubble.h" |
17 #include "ash/shelf/overflow_bubble_view.h" | 18 #include "ash/shelf/overflow_bubble_view.h" |
18 #include "ash/shelf/overflow_button.h" | 19 #include "ash/shelf/overflow_button.h" |
19 #include "ash/shelf/shelf_button.h" | 20 #include "ash/shelf/shelf_button.h" |
20 #include "ash/shelf/shelf_constants.h" | 21 #include "ash/shelf/shelf_constants.h" |
21 #include "ash/shelf/shelf_delegate.h" | 22 #include "ash/shelf/shelf_delegate.h" |
22 #include "ash/shelf/shelf_icon_observer.h" | 23 #include "ash/shelf/shelf_icon_observer.h" |
23 #include "ash/shelf/shelf_item_delegate.h" | 24 #include "ash/shelf/shelf_item_delegate.h" |
24 #include "ash/shelf/shelf_item_delegate_manager.h" | 25 #include "ash/shelf/shelf_item_delegate_manager.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT = 1; | 67 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT = 1; |
67 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT = 2; | 68 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT = 2; |
68 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT = 3; | 69 const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT = 3; |
69 | 70 |
70 // Default amount content is inset on the left edge. | 71 // Default amount content is inset on the left edge. |
71 const int kDefaultLeadingInset = 8; | 72 const int kDefaultLeadingInset = 8; |
72 | 73 |
73 // Minimum distance before drag starts. | 74 // Minimum distance before drag starts. |
74 const int kMinimumDragDistance = 8; | 75 const int kMinimumDragDistance = 8; |
75 | 76 |
| 77 // Size between the buttons. |
| 78 const int kButtonSpacing = 4; |
| 79 const int kAlternateButtonSpacing = 10; |
| 80 |
| 81 // Size allocated to for each button. |
| 82 const int kButtonSize = 44; |
| 83 |
76 // Additional spacing for the left and right side of icons. | 84 // Additional spacing for the left and right side of icons. |
77 const int kHorizontalIconSpacing = 2; | 85 const int kHorizontalIconSpacing = 2; |
78 | 86 |
79 // Inset for items which do not have an icon. | 87 // Inset for items which do not have an icon. |
80 const int kHorizontalNoIconInsetSpacing = | 88 const int kHorizontalNoIconInsetSpacing = |
81 kHorizontalIconSpacing + kDefaultLeadingInset; | 89 kHorizontalIconSpacing + kDefaultLeadingInset; |
82 | 90 |
83 // The proportion of the shelf space reserved for non-panel icons. Panels | 91 // The proportion of the shelf space reserved for non-panel icons. Panels |
84 // may flow into this space but will be put into the overflow bubble if there | 92 // may flow into this space but will be put into the overflow bubble if there |
85 // is contention for the space. | 93 // is contention for the space. |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 void ShelfView::Init() { | 425 void ShelfView::Init() { |
418 model_->AddObserver(this); | 426 model_->AddObserver(this); |
419 | 427 |
420 const ShelfItems& items(model_->items()); | 428 const ShelfItems& items(model_->items()); |
421 for (ShelfItems::const_iterator i = items.begin(); i != items.end(); ++i) { | 429 for (ShelfItems::const_iterator i = items.begin(); i != items.end(); ++i) { |
422 views::View* child = CreateViewForItem(*i); | 430 views::View* child = CreateViewForItem(*i); |
423 child->SetPaintToLayer(true); | 431 child->SetPaintToLayer(true); |
424 view_model_->Add(child, static_cast<int>(i - items.begin())); | 432 view_model_->Add(child, static_cast<int>(i - items.begin())); |
425 AddChildView(child); | 433 AddChildView(child); |
426 } | 434 } |
| 435 ShelfStatusChanged(); |
427 overflow_button_ = new OverflowButton(this); | 436 overflow_button_ = new OverflowButton(this); |
428 overflow_button_->set_context_menu_controller(this); | 437 overflow_button_->set_context_menu_controller(this); |
429 ConfigureChildView(overflow_button_); | 438 ConfigureChildView(overflow_button_); |
430 AddChildView(overflow_button_); | 439 AddChildView(overflow_button_); |
| 440 UpdateFirstButtonPadding(); |
431 | 441 |
432 // We'll layout when our bounds change. | 442 // We'll layout when our bounds change. |
433 } | 443 } |
434 | 444 |
435 void ShelfView::OnShelfAlignmentChanged() { | 445 void ShelfView::OnShelfAlignmentChanged() { |
| 446 UpdateFirstButtonPadding(); |
436 overflow_button_->OnShelfAlignmentChanged(); | 447 overflow_button_->OnShelfAlignmentChanged(); |
437 LayoutToIdealBounds(); | 448 LayoutToIdealBounds(); |
438 for (int i=0; i < view_model_->view_size(); ++i) { | 449 for (int i=0; i < view_model_->view_size(); ++i) { |
| 450 // TODO: remove when AppIcon is a Shelf Button. |
| 451 if (TYPE_APP_LIST == model_->items()[i].type && |
| 452 !ash::switches::UseAlternateShelfLayout()) { |
| 453 static_cast<AppListButton*>(view_model_->view_at(i))->SetImageAlignment( |
| 454 layout_manager_->SelectValueForShelfAlignment( |
| 455 views::ImageButton::ALIGN_CENTER, |
| 456 views::ImageButton::ALIGN_LEFT, |
| 457 views::ImageButton::ALIGN_RIGHT, |
| 458 views::ImageButton::ALIGN_CENTER), |
| 459 layout_manager_->SelectValueForShelfAlignment( |
| 460 views::ImageButton::ALIGN_TOP, |
| 461 views::ImageButton::ALIGN_MIDDLE, |
| 462 views::ImageButton::ALIGN_MIDDLE, |
| 463 views::ImageButton::ALIGN_BOTTOM)); |
| 464 } |
439 if (i >= first_visible_index_ && i <= last_visible_index_) | 465 if (i >= first_visible_index_ && i <= last_visible_index_) |
440 view_model_->view_at(i)->Layout(); | 466 view_model_->view_at(i)->Layout(); |
441 } | 467 } |
442 tooltip_->Close(); | 468 tooltip_->Close(); |
443 if (overflow_bubble_) | 469 if (overflow_bubble_) |
444 overflow_bubble_->Hide(); | 470 overflow_bubble_->Hide(); |
445 } | 471 } |
446 | 472 |
447 void ShelfView::SchedulePaintForAllButtons() { | 473 void ShelfView::SchedulePaintForAllButtons() { |
448 for (int i = 0; i < view_model_->view_size(); ++i) { | 474 for (int i = 0; i < view_model_->view_size(); ++i) { |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 | 708 |
683 IdealBounds ideal_bounds; | 709 IdealBounds ideal_bounds; |
684 CalculateIdealBounds(&ideal_bounds); | 710 CalculateIdealBounds(&ideal_bounds); |
685 views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_); | 711 views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_); |
686 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); | 712 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); |
687 } | 713 } |
688 | 714 |
689 void ShelfView::UpdateAllButtonsVisibilityInOverflowMode() { | 715 void ShelfView::UpdateAllButtonsVisibilityInOverflowMode() { |
690 // The overflow button is not shown in overflow mode. | 716 // The overflow button is not shown in overflow mode. |
691 overflow_button_->SetVisible(false); | 717 overflow_button_->SetVisible(false); |
| 718 int last_button_index = model_->FirstPanelIndex() - 1; |
692 DCHECK_LT(last_visible_index_, view_model_->view_size()); | 719 DCHECK_LT(last_visible_index_, view_model_->view_size()); |
693 for (int i = 0; i < view_model_->view_size(); ++i) { | 720 for (int i = 0; i < view_model_->view_size(); ++i) { |
694 bool visible = i >= first_visible_index_ && | 721 bool visible = i >= first_visible_index_ && |
695 i <= last_visible_index_; | 722 i <= last_visible_index_; |
| 723 if (!ash::switches::UseAlternateShelfLayout()) |
| 724 visible &= i != last_button_index; |
696 | 725 |
697 // To track the dragging of |drag_view_| continuously, its visibility | 726 // To track the dragging of |drag_view_| continuously, its visibility |
698 // should be always true regardless of its position. | 727 // should be always true regardless of its position. |
699 if (dragged_off_from_overflow_to_shelf_ && | 728 if (dragged_off_from_overflow_to_shelf_ && |
700 view_model_->view_at(i) == drag_view_) | 729 view_model_->view_at(i) == drag_view_) |
701 view_model_->view_at(i)->SetVisible(true); | 730 view_model_->view_at(i)->SetVisible(true); |
702 else | 731 else |
703 view_model_->view_at(i)->SetVisible(visible); | 732 view_model_->view_at(i)->SetVisible(visible); |
704 } | 733 } |
705 } | 734 } |
706 | 735 |
707 void ShelfView::CalculateIdealBounds(IdealBounds* bounds) { | 736 void ShelfView::CalculateIdealBounds(IdealBounds* bounds) { |
708 int available_size = layout_manager_->PrimaryAxisValue(width(), height()); | 737 int available_size = layout_manager_->PrimaryAxisValue(width(), height()); |
709 DCHECK(model_->item_count() == view_model_->view_size()); | 738 DCHECK(model_->item_count() == view_model_->view_size()); |
710 if (!available_size) | 739 if (!available_size) |
711 return; | 740 return; |
712 | 741 |
713 int first_panel_index = model_->FirstPanelIndex(); | 742 int first_panel_index = model_->FirstPanelIndex(); |
714 int last_button_index = first_panel_index - 1; | 743 int last_button_index = first_panel_index - 1; |
715 | 744 |
716 int x = 0; | 745 // Initial x,y values account both leading_inset in primary |
717 int y = 0; | 746 // coordinate and secondary coordinate based on the dynamic edge of the |
| 747 // shelf (eg top edge on bottom-aligned shelf). |
| 748 int inset = ash::switches::UseAlternateShelfLayout() ? 0 : leading_inset_; |
| 749 int x = layout_manager_->SelectValueForShelfAlignment(inset, 0, 0, inset); |
| 750 int y = layout_manager_->SelectValueForShelfAlignment(0, inset, inset, 0); |
718 | 751 |
719 int button_size = kShelfButtonSize; | 752 int button_size = GetButtonSize(); |
720 int button_spacing = kShelfButtonSpacing; | 753 int button_spacing = GetButtonSpacing(); |
721 | 754 |
722 int w = layout_manager_->PrimaryAxisValue(button_size, width()); | 755 int w = layout_manager_->PrimaryAxisValue(button_size, width()); |
723 int h = layout_manager_->PrimaryAxisValue(height(), button_size); | 756 int h = layout_manager_->PrimaryAxisValue(height(), button_size); |
724 for (int i = 0; i < view_model_->view_size(); ++i) { | 757 for (int i = 0; i < view_model_->view_size(); ++i) { |
725 if (i < first_visible_index_) { | 758 if (i < first_visible_index_) { |
726 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, 0, 0)); | 759 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, 0, 0)); |
727 continue; | 760 continue; |
728 } | 761 } |
729 | 762 |
730 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); | 763 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); |
731 if (i != last_button_index) { | 764 if (i != last_button_index) { |
732 x = layout_manager_->PrimaryAxisValue(x + w + button_spacing, x); | 765 x = layout_manager_->PrimaryAxisValue(x + w + button_spacing, x); |
733 y = layout_manager_->PrimaryAxisValue(y, y + h + button_spacing); | 766 y = layout_manager_->PrimaryAxisValue(y, y + h + button_spacing); |
734 } | 767 } |
735 } | 768 } |
736 | 769 |
737 if (is_overflow_mode()) { | 770 if (is_overflow_mode()) { |
738 UpdateAllButtonsVisibilityInOverflowMode(); | 771 UpdateAllButtonsVisibilityInOverflowMode(); |
739 return; | 772 return; |
740 } | 773 } |
741 | 774 |
| 775 // To address Fitt's law, we make the first shelf button include the |
| 776 // leading inset (if there is one). |
| 777 if (!ash::switches::UseAlternateShelfLayout()) { |
| 778 if (view_model_->view_size() > 0) { |
| 779 view_model_->set_ideal_bounds(0, gfx::Rect(gfx::Size( |
| 780 layout_manager_->PrimaryAxisValue(inset + w, w), |
| 781 layout_manager_->PrimaryAxisValue(h, inset + h)))); |
| 782 } |
| 783 } |
| 784 |
742 // Right aligned icons. | 785 // Right aligned icons. |
743 int end_position = available_size - button_spacing; | 786 int end_position = available_size - button_spacing; |
744 x = layout_manager_->PrimaryAxisValue(end_position, 0); | 787 x = layout_manager_->PrimaryAxisValue(end_position, 0); |
745 y = layout_manager_->PrimaryAxisValue(0, end_position); | 788 y = layout_manager_->PrimaryAxisValue(0, end_position); |
746 for (int i = view_model_->view_size() - 1; | 789 for (int i = view_model_->view_size() - 1; |
747 i >= first_panel_index; --i) { | 790 i >= first_panel_index; --i) { |
748 x = layout_manager_->PrimaryAxisValue(x - w - button_spacing, x); | 791 x = layout_manager_->PrimaryAxisValue(x - w - button_spacing, x); |
749 y = layout_manager_->PrimaryAxisValue(y, y - h - button_spacing); | 792 y = layout_manager_->PrimaryAxisValue(y, y - h - button_spacing); |
750 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); | 793 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); |
751 end_position = layout_manager_->PrimaryAxisValue(x, y); | 794 end_position = layout_manager_->PrimaryAxisValue(x, y); |
752 } | 795 } |
753 | 796 |
754 // Icons on the left / top are guaranteed up to kLeftIconProportion of | 797 // Icons on the left / top are guaranteed up to kLeftIconProportion of |
755 // the available space. | 798 // the available space. |
756 int last_icon_position = layout_manager_->PrimaryAxisValue( | 799 int last_icon_position = layout_manager_->PrimaryAxisValue( |
757 view_model_->ideal_bounds(last_button_index).right(), | 800 view_model_->ideal_bounds(last_button_index).right(), |
758 view_model_->ideal_bounds(last_button_index).bottom()) | 801 view_model_->ideal_bounds(last_button_index).bottom()) |
759 + button_size; | 802 + button_size + inset; |
| 803 if (!ash::switches::UseAlternateShelfLayout()) |
| 804 last_icon_position += button_size; |
760 int reserved_icon_space = available_size * kReservedNonPanelIconProportion; | 805 int reserved_icon_space = available_size * kReservedNonPanelIconProportion; |
761 if (last_icon_position < reserved_icon_space) | 806 if (last_icon_position < reserved_icon_space) |
762 end_position = last_icon_position; | 807 end_position = last_icon_position; |
763 else | 808 else |
764 end_position = std::max(end_position, reserved_icon_space); | 809 end_position = std::max(end_position, reserved_icon_space); |
765 | 810 |
766 bounds->overflow_bounds.set_size( | 811 bounds->overflow_bounds.set_size( |
767 gfx::Size(layout_manager_->PrimaryAxisValue(w, width()), | 812 gfx::Size(layout_manager_->PrimaryAxisValue(w, width()), |
768 layout_manager_->PrimaryAxisValue(height(), h))); | 813 layout_manager_->PrimaryAxisValue(height(), h))); |
769 | 814 |
770 last_visible_index_ = DetermineLastVisibleIndex( | 815 if (ash::switches::UseAlternateShelfLayout()) { |
771 end_position - button_size); | 816 last_visible_index_ = DetermineLastVisibleIndex( |
| 817 end_position - button_size); |
| 818 } else { |
| 819 last_visible_index_ = DetermineLastVisibleIndex( |
| 820 end_position - inset - 2 * button_size); |
| 821 } |
772 last_hidden_index_ = DetermineFirstVisiblePanelIndex(end_position) - 1; | 822 last_hidden_index_ = DetermineFirstVisiblePanelIndex(end_position) - 1; |
773 bool show_overflow = (last_visible_index_ < last_button_index || | 823 bool show_overflow = |
774 last_hidden_index_ >= first_panel_index); | 824 ((ash::switches::UseAlternateShelfLayout() ? 0 : 1) + |
| 825 last_visible_index_ < last_button_index || |
| 826 last_hidden_index_ >= first_panel_index); |
775 | 827 |
776 // Create Space for the overflow button | 828 // Create Space for the overflow button |
777 if (show_overflow && last_visible_index_ > 0 && | 829 if (show_overflow && ash::switches::UseAlternateShelfLayout() && |
778 last_visible_index_ < last_button_index) | 830 last_visible_index_ > 0 && last_visible_index_ < last_button_index) |
779 --last_visible_index_; | 831 --last_visible_index_; |
780 for (int i = 0; i < view_model_->view_size(); ++i) { | 832 for (int i = 0; i < view_model_->view_size(); ++i) { |
781 bool visible = i <= last_visible_index_ || i > last_hidden_index_; | 833 bool visible = i <= last_visible_index_ || i > last_hidden_index_; |
| 834 // Always show the app list. |
| 835 if (!ash::switches::UseAlternateShelfLayout()) |
| 836 visible |= (i == last_button_index); |
782 // To receive drag event continously from |drag_view_| during the dragging | 837 // To receive drag event continously from |drag_view_| during the dragging |
783 // off from the shelf, don't make |drag_view_| invisible. It will be | 838 // off from the shelf, don't make |drag_view_| invisible. It will be |
784 // eventually invisible and removed from the |view_model_| by | 839 // eventually invisible and removed from the |view_model_| by |
785 // FinalizeRipOffDrag(). | 840 // FinalizeRipOffDrag(). |
786 if (dragged_off_shelf_ && view_model_->view_at(i) == drag_view_) | 841 if (dragged_off_shelf_ && view_model_->view_at(i) == drag_view_) |
787 continue; | 842 continue; |
788 view_model_->view_at(i)->SetVisible(visible); | 843 view_model_->view_at(i)->SetVisible(visible); |
789 } | 844 } |
790 | 845 |
791 overflow_button_->SetVisible(show_overflow); | 846 overflow_button_->SetVisible(show_overflow); |
792 if (show_overflow) { | 847 if (show_overflow) { |
793 DCHECK_NE(0, view_model_->view_size()); | 848 DCHECK_NE(0, view_model_->view_size()); |
794 if (last_visible_index_ == -1) { | 849 if (last_visible_index_ == -1) { |
795 x = 0; | 850 x = layout_manager_->SelectValueForShelfAlignment(inset, 0, 0, inset); |
796 y = 0; | 851 y = layout_manager_->SelectValueForShelfAlignment(0, inset, inset, 0); |
| 852 } else if (last_visible_index_ == last_button_index |
| 853 && !ash::switches::UseAlternateShelfLayout()) { |
| 854 x = view_model_->ideal_bounds(last_visible_index_).x(); |
| 855 y = view_model_->ideal_bounds(last_visible_index_).y(); |
797 } else { | 856 } else { |
798 x = layout_manager_->PrimaryAxisValue( | 857 x = layout_manager_->PrimaryAxisValue( |
799 view_model_->ideal_bounds(last_visible_index_).right(), | 858 view_model_->ideal_bounds(last_visible_index_).right(), |
800 view_model_->ideal_bounds(last_visible_index_).x()); | 859 view_model_->ideal_bounds(last_visible_index_).x()); |
801 y = layout_manager_->PrimaryAxisValue( | 860 y = layout_manager_->PrimaryAxisValue( |
802 view_model_->ideal_bounds(last_visible_index_).y(), | 861 view_model_->ideal_bounds(last_visible_index_).y(), |
803 view_model_->ideal_bounds(last_visible_index_).bottom()); | 862 view_model_->ideal_bounds(last_visible_index_).bottom()); |
804 } | 863 } |
805 // Set all hidden panel icon positions to be on the overflow button. | 864 // Set all hidden panel icon positions to be on the overflow button. |
806 for (int i = first_panel_index; i <= last_hidden_index_; ++i) | 865 for (int i = first_panel_index; i <= last_hidden_index_; ++i) |
807 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); | 866 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); |
808 | 867 |
809 // Add more space between last visible item and overflow button. | 868 // Add more space between last visible item and overflow button. |
810 // Without this, two buttons look too close compared with other items. | 869 // Without this, two buttons look too close compared with other items. |
811 x = layout_manager_->PrimaryAxisValue(x + button_spacing, x); | 870 if (ash::switches::UseAlternateShelfLayout()) { |
812 y = layout_manager_->PrimaryAxisValue(y, y + button_spacing); | 871 x = layout_manager_->PrimaryAxisValue(x + button_spacing, x); |
| 872 y = layout_manager_->PrimaryAxisValue(y, y + button_spacing); |
| 873 } |
813 | 874 |
814 bounds->overflow_bounds.set_x(x); | 875 bounds->overflow_bounds.set_x(x); |
815 bounds->overflow_bounds.set_y(y); | 876 bounds->overflow_bounds.set_y(y); |
| 877 if (!ash::switches::UseAlternateShelfLayout()) { |
| 878 // Position app list after overflow button. |
| 879 gfx::Rect app_list_bounds = view_model_->ideal_bounds(last_button_index); |
| 880 |
| 881 x = layout_manager_->PrimaryAxisValue(x + w + button_spacing, x); |
| 882 y = layout_manager_->PrimaryAxisValue(y, y + h + button_spacing); |
| 883 app_list_bounds.set_x(x); |
| 884 app_list_bounds.set_y(y); |
| 885 view_model_->set_ideal_bounds(last_button_index, app_list_bounds); |
| 886 } |
816 if (overflow_bubble_.get() && overflow_bubble_->IsShowing()) | 887 if (overflow_bubble_.get() && overflow_bubble_->IsShowing()) |
817 UpdateOverflowRange(overflow_bubble_->shelf_view()); | 888 UpdateOverflowRange(overflow_bubble_->shelf_view()); |
818 } else { | 889 } else { |
819 if (overflow_bubble_) | 890 if (overflow_bubble_) |
820 overflow_bubble_->Hide(); | 891 overflow_bubble_->Hide(); |
821 } | 892 } |
822 } | 893 } |
823 | 894 |
824 int ShelfView::DetermineLastVisibleIndex(int max_value) const { | 895 int ShelfView::DetermineLastVisibleIndex(int max_value) const { |
825 int index = model_->FirstPanelIndex() - 1; | 896 int index = model_->FirstPanelIndex() - 1; |
(...skipping 28 matching lines...) Expand all Loading... |
854 void ShelfView::AnimateToIdealBounds() { | 925 void ShelfView::AnimateToIdealBounds() { |
855 IdealBounds ideal_bounds; | 926 IdealBounds ideal_bounds; |
856 CalculateIdealBounds(&ideal_bounds); | 927 CalculateIdealBounds(&ideal_bounds); |
857 for (int i = 0; i < view_model_->view_size(); ++i) { | 928 for (int i = 0; i < view_model_->view_size(); ++i) { |
858 View* view = view_model_->view_at(i); | 929 View* view = view_model_->view_at(i); |
859 bounds_animator_->AnimateViewTo(view, view_model_->ideal_bounds(i)); | 930 bounds_animator_->AnimateViewTo(view, view_model_->ideal_bounds(i)); |
860 // Now that the item animation starts, we have to make sure that the | 931 // Now that the item animation starts, we have to make sure that the |
861 // padding of the first gets properly transferred to the new first item. | 932 // padding of the first gets properly transferred to the new first item. |
862 if (i && view->border()) | 933 if (i && view->border()) |
863 view->SetBorder(views::Border::NullBorder()); | 934 view->SetBorder(views::Border::NullBorder()); |
| 935 else if (!i && !view->border()) |
| 936 UpdateFirstButtonPadding(); |
864 } | 937 } |
865 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); | 938 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); |
866 } | 939 } |
867 | 940 |
868 views::View* ShelfView::CreateViewForItem(const ShelfItem& item) { | 941 views::View* ShelfView::CreateViewForItem(const ShelfItem& item) { |
869 views::View* view = NULL; | 942 views::View* view = NULL; |
870 switch (item.type) { | 943 switch (item.type) { |
871 case TYPE_BROWSER_SHORTCUT: | 944 case TYPE_BROWSER_SHORTCUT: |
872 case TYPE_APP_SHORTCUT: | 945 case TYPE_APP_SHORTCUT: |
873 case TYPE_WINDOWED_APP: | 946 case TYPE_WINDOWED_APP: |
874 case TYPE_PLATFORM_APP: | 947 case TYPE_PLATFORM_APP: |
875 case TYPE_DIALOG: | 948 case TYPE_DIALOG: |
876 case TYPE_APP_PANEL: { | 949 case TYPE_APP_PANEL: { |
877 ShelfButton* button = ShelfButton::Create(this, this, layout_manager_); | 950 ShelfButton* button = ShelfButton::Create(this, this, layout_manager_); |
878 button->SetImage(item.image); | 951 button->SetImage(item.image); |
879 ReflectItemStatus(item, button); | 952 ReflectItemStatus(item, button); |
880 view = button; | 953 view = button; |
881 break; | 954 break; |
882 } | 955 } |
883 | 956 |
884 case TYPE_APP_LIST: { | 957 case TYPE_APP_LIST: { |
885 view = new AppListButton(this, this, layout_manager_->shelf_widget()); | 958 if (ash::switches::UseAlternateShelfLayout()) { |
| 959 view = new AlternateAppListButton(this, |
| 960 this, |
| 961 layout_manager_->shelf_widget()); |
| 962 } else { |
| 963 // TODO(dave): turn this into a ShelfButton too. |
| 964 AppListButton* button = new AppListButton(this, this); |
| 965 button->SetImageAlignment( |
| 966 layout_manager_->SelectValueForShelfAlignment( |
| 967 views::ImageButton::ALIGN_CENTER, |
| 968 views::ImageButton::ALIGN_LEFT, |
| 969 views::ImageButton::ALIGN_RIGHT, |
| 970 views::ImageButton::ALIGN_CENTER), |
| 971 layout_manager_->SelectValueForShelfAlignment( |
| 972 views::ImageButton::ALIGN_TOP, |
| 973 views::ImageButton::ALIGN_MIDDLE, |
| 974 views::ImageButton::ALIGN_MIDDLE, |
| 975 views::ImageButton::ALIGN_BOTTOM)); |
| 976 view = button; |
| 977 } |
886 break; | 978 break; |
887 } | 979 } |
888 | 980 |
889 default: | 981 default: |
890 break; | 982 break; |
891 } | 983 } |
892 view->set_context_menu_controller(this); | 984 view->set_context_menu_controller(this); |
893 | 985 |
894 DCHECK(view); | 986 DCHECK(view); |
895 ConfigureChildView(view); | 987 ConfigureChildView(view); |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1232 overflow_view->set_owner_overflow_bubble(overflow_bubble_.get()); | 1324 overflow_view->set_owner_overflow_bubble(overflow_bubble_.get()); |
1233 overflow_view->OnShelfAlignmentChanged(); | 1325 overflow_view->OnShelfAlignmentChanged(); |
1234 overflow_view->main_shelf_ = this; | 1326 overflow_view->main_shelf_ = this; |
1235 UpdateOverflowRange(overflow_view); | 1327 UpdateOverflowRange(overflow_view); |
1236 | 1328 |
1237 overflow_bubble_->Show(overflow_button_, overflow_view); | 1329 overflow_bubble_->Show(overflow_button_, overflow_view); |
1238 | 1330 |
1239 Shell::GetInstance()->UpdateShelfVisibility(); | 1331 Shell::GetInstance()->UpdateShelfVisibility(); |
1240 } | 1332 } |
1241 | 1333 |
| 1334 void ShelfView::UpdateFirstButtonPadding() { |
| 1335 if (ash::switches::UseAlternateShelfLayout()) |
| 1336 return; |
| 1337 |
| 1338 // Creates an empty border for first shelf button to make included leading |
| 1339 // inset act as the button's padding. This is only needed on button creation |
| 1340 // and when shelf alignment changes. |
| 1341 if (view_model_->view_size() > 0) { |
| 1342 view_model_->view_at(0)->SetBorder(views::Border::CreateEmptyBorder( |
| 1343 layout_manager_->PrimaryAxisValue(0, leading_inset_), |
| 1344 layout_manager_->PrimaryAxisValue(leading_inset_, 0), |
| 1345 0, |
| 1346 0)); |
| 1347 } |
| 1348 } |
| 1349 |
1242 void ShelfView::OnFadeOutAnimationEnded() { | 1350 void ShelfView::OnFadeOutAnimationEnded() { |
1243 AnimateToIdealBounds(); | 1351 AnimateToIdealBounds(); |
1244 StartFadeInLastVisibleItem(); | 1352 StartFadeInLastVisibleItem(); |
1245 } | 1353 } |
1246 | 1354 |
1247 void ShelfView::StartFadeInLastVisibleItem() { | 1355 void ShelfView::StartFadeInLastVisibleItem() { |
1248 // If overflow button is visible and there is a valid new last item, fading | 1356 // If overflow button is visible and there is a valid new last item, fading |
1249 // the new last item in after sliding animation is finished. | 1357 // the new last item in after sliding animation is finished. |
1250 if (overflow_button_->visible() && last_visible_index_ >= 0) { | 1358 if (overflow_button_->visible() && last_visible_index_ >= 0) { |
1251 views::View* last_visible_view = view_model_->view_at(last_visible_index_); | 1359 views::View* last_visible_view = view_model_->view_at(last_visible_index_); |
1252 last_visible_view->layer()->SetOpacity(0); | 1360 last_visible_view->layer()->SetOpacity(0); |
1253 bounds_animator_->SetAnimationDelegate( | 1361 bounds_animator_->SetAnimationDelegate( |
1254 last_visible_view, | 1362 last_visible_view, |
1255 new ShelfView::StartFadeAnimationDelegate(this, last_visible_view), | 1363 new ShelfView::StartFadeAnimationDelegate(this, last_visible_view), |
1256 true); | 1364 true); |
1257 } | 1365 } |
1258 } | 1366 } |
1259 | 1367 |
1260 void ShelfView::UpdateOverflowRange(ShelfView* overflow_view) { | 1368 void ShelfView::UpdateOverflowRange(ShelfView* overflow_view) { |
1261 const int first_overflow_index = last_visible_index_ + 1; | 1369 const int first_overflow_index = last_visible_index_ + 1; |
1262 const int last_overflow_index = last_hidden_index_; | 1370 const int last_overflow_index = last_hidden_index_; |
1263 DCHECK_LE(first_overflow_index, last_overflow_index); | 1371 DCHECK_LE(first_overflow_index, last_overflow_index); |
1264 DCHECK_LT(last_overflow_index, view_model_->view_size()); | 1372 DCHECK_LT(last_overflow_index, view_model_->view_size()); |
1265 | 1373 |
1266 overflow_view->first_visible_index_ = first_overflow_index; | 1374 overflow_view->first_visible_index_ = first_overflow_index; |
1267 overflow_view->last_visible_index_ = last_overflow_index; | 1375 overflow_view->last_visible_index_ = last_overflow_index; |
1268 } | 1376 } |
1269 | 1377 |
| 1378 int ShelfView::GetButtonSize() const { |
| 1379 return ash::switches::UseAlternateShelfLayout() ? |
| 1380 kButtonSize : kShelfPreferredSize; |
| 1381 } |
| 1382 |
| 1383 int ShelfView::GetButtonSpacing() const { |
| 1384 return ash::switches::UseAlternateShelfLayout() ? |
| 1385 kAlternateButtonSpacing : kButtonSpacing; |
| 1386 } |
| 1387 |
1270 bool ShelfView::ShouldHideTooltip(const gfx::Point& cursor_location) { | 1388 bool ShelfView::ShouldHideTooltip(const gfx::Point& cursor_location) { |
1271 gfx::Rect active_bounds; | 1389 gfx::Rect active_bounds; |
1272 | 1390 |
1273 for (int i = 0; i < child_count(); ++i) { | 1391 for (int i = 0; i < child_count(); ++i) { |
1274 views::View* child = child_at(i); | 1392 views::View* child = child_at(i); |
1275 if (child == overflow_button_) | 1393 if (child == overflow_button_) |
1276 continue; | 1394 continue; |
1277 if (!ShouldShowTooltipForView(child)) | 1395 if (!ShouldShowTooltipForView(child)) |
1278 continue; | 1396 continue; |
1279 | 1397 |
(...skipping 12 matching lines...) Expand all Loading... |
1292 } | 1410 } |
1293 | 1411 |
1294 gfx::Rect ShelfView::GetBoundsForDragInsertInScreen() { | 1412 gfx::Rect ShelfView::GetBoundsForDragInsertInScreen() { |
1295 gfx::Size preferred_size; | 1413 gfx::Size preferred_size; |
1296 if (is_overflow_mode()) { | 1414 if (is_overflow_mode()) { |
1297 DCHECK(owner_overflow_bubble_); | 1415 DCHECK(owner_overflow_bubble_); |
1298 gfx::Rect bubble_bounds = | 1416 gfx::Rect bubble_bounds = |
1299 owner_overflow_bubble_->bubble_view()->GetBubbleBounds(); | 1417 owner_overflow_bubble_->bubble_view()->GetBubbleBounds(); |
1300 preferred_size = bubble_bounds.size(); | 1418 preferred_size = bubble_bounds.size(); |
1301 } else { | 1419 } else { |
| 1420 const int preferred_shelf_size = layout_manager_->GetPreferredShelfSize(); |
| 1421 |
1302 const int last_button_index = view_model_->view_size() - 1; | 1422 const int last_button_index = view_model_->view_size() - 1; |
1303 gfx::Rect last_button_bounds = | 1423 gfx::Rect last_button_bounds = |
1304 view_model_->view_at(last_button_index)->bounds(); | 1424 view_model_->view_at(last_button_index)->bounds(); |
1305 if (overflow_button_->visible() && | 1425 if (overflow_button_->visible() && |
1306 model_->GetItemIndexForType(TYPE_APP_PANEL) == -1) { | 1426 model_->GetItemIndexForType(TYPE_APP_PANEL) == -1) { |
1307 // When overflow button is visible and shelf has no panel items, | 1427 // When overflow button is visible and shelf has no panel items, |
1308 // last_button_bounds should be overflow button's bounds. | 1428 // last_button_bounds should be overflow button's bounds. |
1309 last_button_bounds = overflow_button_->bounds(); | 1429 last_button_bounds = overflow_button_->bounds(); |
1310 } | 1430 } |
1311 | 1431 |
1312 if (layout_manager_->IsHorizontalAlignment()) { | 1432 if (layout_manager_->IsHorizontalAlignment()) { |
1313 preferred_size = gfx::Size(last_button_bounds.right() + leading_inset_, | 1433 preferred_size = gfx::Size(last_button_bounds.right() + leading_inset_, |
1314 kShelfSize); | 1434 preferred_shelf_size); |
1315 } else { | 1435 } else { |
1316 preferred_size = gfx::Size(kShelfSize, | 1436 preferred_size = gfx::Size(preferred_shelf_size, |
1317 last_button_bounds.bottom() + leading_inset_); | 1437 last_button_bounds.bottom() + leading_inset_); |
1318 } | 1438 } |
1319 } | 1439 } |
1320 gfx::Point origin(GetMirroredXWithWidthInView(0, preferred_size.width()), 0); | 1440 gfx::Point origin(GetMirroredXWithWidthInView(0, preferred_size.width()), 0); |
1321 | 1441 |
1322 // In overflow mode, we should use OverflowBubbleView as a source for | 1442 // In overflow mode, we should use OverflowBubbleView as a source for |
1323 // converting |origin| to screen coordinates. When a scroll operation is | 1443 // converting |origin| to screen coordinates. When a scroll operation is |
1324 // occurred in OverflowBubble, the bounds of ShelfView in OverflowBubble can | 1444 // occurred in OverflowBubble, the bounds of ShelfView in OverflowBubble can |
1325 // be changed. | 1445 // be changed. |
1326 if (is_overflow_mode()) | 1446 if (is_overflow_mode()) |
(...skipping 30 matching lines...) Expand all Loading... |
1357 // the list. | 1477 // the list. |
1358 if (at_end) | 1478 if (at_end) |
1359 return view_model_->view_size(); | 1479 return view_model_->view_size(); |
1360 return modified_view ? view_model_->GetIndexOfView(modified_view) : -1; | 1480 return modified_view ? view_model_->GetIndexOfView(modified_view) : -1; |
1361 } | 1481 } |
1362 | 1482 |
1363 gfx::Size ShelfView::GetPreferredSize() { | 1483 gfx::Size ShelfView::GetPreferredSize() { |
1364 IdealBounds ideal_bounds; | 1484 IdealBounds ideal_bounds; |
1365 CalculateIdealBounds(&ideal_bounds); | 1485 CalculateIdealBounds(&ideal_bounds); |
1366 | 1486 |
| 1487 const int preferred_size = layout_manager_->GetPreferredShelfSize(); |
| 1488 |
1367 int last_button_index = is_overflow_mode() ? | 1489 int last_button_index = is_overflow_mode() ? |
1368 last_visible_index_ : view_model_->view_size() - 1; | 1490 last_visible_index_ : view_model_->view_size() - 1; |
1369 | 1491 |
1370 // When an item is dragged off from the overflow bubble, it is moved to last | 1492 // When an item is dragged off from the overflow bubble, it is moved to last |
1371 // position and and changed to invisible. Overflow bubble size should be | 1493 // position and and changed to invisible. Overflow bubble size should be |
1372 // shrunk to fit only for visible items. | 1494 // shrunk to fit only for visible items. |
1373 // If |dragged_off_from_overflow_to_shelf_| is set, there will be no invisible | 1495 // If |dragged_off_from_overflow_to_shelf_| is set, there will be no invisible |
1374 // items in the shelf. | 1496 // items in the shelf. |
1375 if (is_overflow_mode() && | 1497 if (is_overflow_mode() && |
1376 dragged_off_shelf_ && | 1498 dragged_off_shelf_ && |
1377 !dragged_off_from_overflow_to_shelf_ && | 1499 !dragged_off_from_overflow_to_shelf_ && |
1378 RemovableByRipOff(view_model_->GetIndexOfView(drag_view_)) == REMOVABLE) | 1500 RemovableByRipOff(view_model_->GetIndexOfView(drag_view_)) == REMOVABLE) |
1379 last_button_index--; | 1501 last_button_index--; |
1380 | 1502 |
1381 const gfx::Rect last_button_bounds = | 1503 const gfx::Rect last_button_bounds = |
1382 last_button_index >= first_visible_index_ ? | 1504 last_button_index >= first_visible_index_ ? |
1383 view_model_->ideal_bounds(last_button_index) : | 1505 view_model_->ideal_bounds(last_button_index) : |
1384 gfx::Rect(gfx::Size(kShelfSize, kShelfSize)); | 1506 gfx::Rect(gfx::Size(preferred_size, preferred_size)); |
1385 | 1507 |
1386 if (layout_manager_->IsHorizontalAlignment()) { | 1508 if (layout_manager_->IsHorizontalAlignment()) { |
1387 return gfx::Size(last_button_bounds.right() + leading_inset_, kShelfSize); | 1509 return gfx::Size(last_button_bounds.right() + leading_inset_, |
| 1510 preferred_size); |
1388 } | 1511 } |
1389 | 1512 |
1390 return gfx::Size(kShelfSize, | 1513 return gfx::Size(preferred_size, |
1391 last_button_bounds.bottom() + leading_inset_); | 1514 last_button_bounds.bottom() + leading_inset_); |
1392 } | 1515 } |
1393 | 1516 |
1394 void ShelfView::OnBoundsChanged(const gfx::Rect& previous_bounds) { | 1517 void ShelfView::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
1395 // This bounds change is produced by the shelf movement and all content has | 1518 // This bounds change is produced by the shelf movement and all content has |
1396 // to follow. Using an animation at that time would produce a time lag since | 1519 // to follow. Using an animation at that time would produce a time lag since |
1397 // the animation of the BoundsAnimator has itself a delay before it arrives | 1520 // the animation of the BoundsAnimator has itself a delay before it arrives |
1398 // at the required location. As such we tell the animator to go there | 1521 // at the required location. As such we tell the animator to go there |
1399 // immediately. | 1522 // immediately. |
1400 BoundsAnimatorDisabler disabler(bounds_animator_.get()); | 1523 BoundsAnimatorDisabler disabler(bounds_animator_.get()); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 view_model_->Move(start_index, target_index); | 1668 view_model_->Move(start_index, target_index); |
1546 // When cancelling a drag due to a shelf item being added, the currently | 1669 // When cancelling a drag due to a shelf item being added, the currently |
1547 // dragged item is moved back to its initial position. AnimateToIdealBounds | 1670 // dragged item is moved back to its initial position. AnimateToIdealBounds |
1548 // will be called again when the new item is added to the |view_model_| but | 1671 // will be called again when the new item is added to the |view_model_| but |
1549 // at this time the |view_model_| is inconsistent with the |model_|. | 1672 // at this time the |view_model_| is inconsistent with the |model_|. |
1550 if (!cancelling_drag_model_changed_) | 1673 if (!cancelling_drag_model_changed_) |
1551 AnimateToIdealBounds(); | 1674 AnimateToIdealBounds(); |
1552 } | 1675 } |
1553 | 1676 |
1554 void ShelfView::ShelfStatusChanged() { | 1677 void ShelfView::ShelfStatusChanged() { |
1555 // Nothing to do here. | 1678 if (ash::switches::UseAlternateShelfLayout()) |
| 1679 return; |
| 1680 AppListButton* app_list_button = |
| 1681 static_cast<AppListButton*>(GetAppListButtonView()); |
| 1682 if (model_->status() == ShelfModel::STATUS_LOADING) |
| 1683 app_list_button->StartLoadingAnimation(); |
| 1684 else |
| 1685 app_list_button->StopLoadingAnimation(); |
1556 } | 1686 } |
1557 | 1687 |
1558 void ShelfView::PointerPressedOnButton(views::View* view, | 1688 void ShelfView::PointerPressedOnButton(views::View* view, |
1559 Pointer pointer, | 1689 Pointer pointer, |
1560 const ui::LocatedEvent& event) { | 1690 const ui::LocatedEvent& event) { |
1561 if (drag_view_) | 1691 if (drag_view_) |
1562 return; | 1692 return; |
1563 | 1693 |
1564 int index = view_model_->GetIndexOfView(view); | 1694 int index = view_model_->GetIndexOfView(view); |
1565 if (index == -1) | 1695 if (index == -1) |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1922 break; | 2052 break; |
1923 case SHELF_ALIGNMENT_TOP: | 2053 case SHELF_ALIGNMENT_TOP: |
1924 distance = coordinate.y() - bounds.bottom(); | 2054 distance = coordinate.y() - bounds.bottom(); |
1925 break; | 2055 break; |
1926 } | 2056 } |
1927 return distance > 0 ? distance : 0; | 2057 return distance > 0 ? distance : 0; |
1928 } | 2058 } |
1929 | 2059 |
1930 } // namespace internal | 2060 } // namespace internal |
1931 } // namespace ash | 2061 } // namespace ash |
OLD | NEW |