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