| 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 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 | 704 |
| 679 IdealBounds ideal_bounds; | 705 IdealBounds ideal_bounds; |
| 680 CalculateIdealBounds(&ideal_bounds); | 706 CalculateIdealBounds(&ideal_bounds); |
| 681 views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_); | 707 views::ViewModelUtils::SetViewBoundsToIdealBounds(*view_model_); |
| 682 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); | 708 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); |
| 683 } | 709 } |
| 684 | 710 |
| 685 void ShelfView::UpdateAllButtonsVisibilityInOverflowMode() { | 711 void ShelfView::UpdateAllButtonsVisibilityInOverflowMode() { |
| 686 // The overflow button is not shown in overflow mode. | 712 // The overflow button is not shown in overflow mode. |
| 687 overflow_button_->SetVisible(false); | 713 overflow_button_->SetVisible(false); |
| 714 int last_button_index = model_->FirstPanelIndex() - 1; |
| 688 DCHECK_LT(last_visible_index_, view_model_->view_size()); | 715 DCHECK_LT(last_visible_index_, view_model_->view_size()); |
| 689 for (int i = 0; i < view_model_->view_size(); ++i) { | 716 for (int i = 0; i < view_model_->view_size(); ++i) { |
| 690 bool visible = i >= first_visible_index_ && | 717 bool visible = i >= first_visible_index_ && |
| 691 i <= last_visible_index_; | 718 i <= last_visible_index_; |
| 719 if (!ash::switches::UseAlternateShelfLayout()) |
| 720 visible &= i != last_button_index; |
| 692 | 721 |
| 693 // To track the dragging of |drag_view_| continuously, its visibility | 722 // To track the dragging of |drag_view_| continuously, its visibility |
| 694 // should be always true regardless of its position. | 723 // should be always true regardless of its position. |
| 695 if (dragged_off_from_overflow_to_shelf_ && | 724 if (dragged_off_from_overflow_to_shelf_ && |
| 696 view_model_->view_at(i) == drag_view_) | 725 view_model_->view_at(i) == drag_view_) |
| 697 view_model_->view_at(i)->SetVisible(true); | 726 view_model_->view_at(i)->SetVisible(true); |
| 698 else | 727 else |
| 699 view_model_->view_at(i)->SetVisible(visible); | 728 view_model_->view_at(i)->SetVisible(visible); |
| 700 } | 729 } |
| 701 } | 730 } |
| 702 | 731 |
| 703 void ShelfView::CalculateIdealBounds(IdealBounds* bounds) { | 732 void ShelfView::CalculateIdealBounds(IdealBounds* bounds) { |
| 704 int available_size = layout_manager_->PrimaryAxisValue(width(), height()); | 733 int available_size = layout_manager_->PrimaryAxisValue(width(), height()); |
| 705 DCHECK(model_->item_count() == view_model_->view_size()); | 734 DCHECK(model_->item_count() == view_model_->view_size()); |
| 706 if (!available_size) | 735 if (!available_size) |
| 707 return; | 736 return; |
| 708 | 737 |
| 709 int first_panel_index = model_->FirstPanelIndex(); | 738 int first_panel_index = model_->FirstPanelIndex(); |
| 710 int last_button_index = first_panel_index - 1; | 739 int last_button_index = first_panel_index - 1; |
| 711 | 740 |
| 712 int x = 0; | 741 // Initial x,y values account both leading_inset in primary |
| 713 int y = 0; | 742 // coordinate and secondary coordinate based on the dynamic edge of the |
| 743 // shelf (eg top edge on bottom-aligned shelf). |
| 744 int inset = ash::switches::UseAlternateShelfLayout() ? 0 : leading_inset_; |
| 745 int x = layout_manager_->SelectValueForShelfAlignment(inset, 0, 0, inset); |
| 746 int y = layout_manager_->SelectValueForShelfAlignment(0, inset, inset, 0); |
| 714 | 747 |
| 715 int button_size = kShelfButtonSize; | 748 int button_size = GetButtonSize(); |
| 716 int button_spacing = kShelfButtonSpacing; | 749 int button_spacing = GetButtonSpacing(); |
| 717 | 750 |
| 718 int w = layout_manager_->PrimaryAxisValue(button_size, width()); | 751 int w = layout_manager_->PrimaryAxisValue(button_size, width()); |
| 719 int h = layout_manager_->PrimaryAxisValue(height(), button_size); | 752 int h = layout_manager_->PrimaryAxisValue(height(), button_size); |
| 720 for (int i = 0; i < view_model_->view_size(); ++i) { | 753 for (int i = 0; i < view_model_->view_size(); ++i) { |
| 721 if (i < first_visible_index_) { | 754 if (i < first_visible_index_) { |
| 722 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, 0, 0)); | 755 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, 0, 0)); |
| 723 continue; | 756 continue; |
| 724 } | 757 } |
| 725 | 758 |
| 726 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); | 759 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); |
| 727 if (i != last_button_index) { | 760 if (i != last_button_index) { |
| 728 x = layout_manager_->PrimaryAxisValue(x + w + button_spacing, x); | 761 x = layout_manager_->PrimaryAxisValue(x + w + button_spacing, x); |
| 729 y = layout_manager_->PrimaryAxisValue(y, y + h + button_spacing); | 762 y = layout_manager_->PrimaryAxisValue(y, y + h + button_spacing); |
| 730 } | 763 } |
| 731 } | 764 } |
| 732 | 765 |
| 733 if (is_overflow_mode()) { | 766 if (is_overflow_mode()) { |
| 734 UpdateAllButtonsVisibilityInOverflowMode(); | 767 UpdateAllButtonsVisibilityInOverflowMode(); |
| 735 return; | 768 return; |
| 736 } | 769 } |
| 737 | 770 |
| 771 // To address Fitt's law, we make the first shelf button include the |
| 772 // leading inset (if there is one). |
| 773 if (!ash::switches::UseAlternateShelfLayout()) { |
| 774 if (view_model_->view_size() > 0) { |
| 775 view_model_->set_ideal_bounds(0, gfx::Rect(gfx::Size( |
| 776 layout_manager_->PrimaryAxisValue(inset + w, w), |
| 777 layout_manager_->PrimaryAxisValue(h, inset + h)))); |
| 778 } |
| 779 } |
| 780 |
| 738 // Right aligned icons. | 781 // Right aligned icons. |
| 739 int end_position = available_size - button_spacing; | 782 int end_position = available_size - button_spacing; |
| 740 x = layout_manager_->PrimaryAxisValue(end_position, 0); | 783 x = layout_manager_->PrimaryAxisValue(end_position, 0); |
| 741 y = layout_manager_->PrimaryAxisValue(0, end_position); | 784 y = layout_manager_->PrimaryAxisValue(0, end_position); |
| 742 for (int i = view_model_->view_size() - 1; | 785 for (int i = view_model_->view_size() - 1; |
| 743 i >= first_panel_index; --i) { | 786 i >= first_panel_index; --i) { |
| 744 x = layout_manager_->PrimaryAxisValue(x - w - button_spacing, x); | 787 x = layout_manager_->PrimaryAxisValue(x - w - button_spacing, x); |
| 745 y = layout_manager_->PrimaryAxisValue(y, y - h - button_spacing); | 788 y = layout_manager_->PrimaryAxisValue(y, y - h - button_spacing); |
| 746 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); | 789 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); |
| 747 end_position = layout_manager_->PrimaryAxisValue(x, y); | 790 end_position = layout_manager_->PrimaryAxisValue(x, y); |
| 748 } | 791 } |
| 749 | 792 |
| 750 // Icons on the left / top are guaranteed up to kLeftIconProportion of | 793 // Icons on the left / top are guaranteed up to kLeftIconProportion of |
| 751 // the available space. | 794 // the available space. |
| 752 int last_icon_position = layout_manager_->PrimaryAxisValue( | 795 int last_icon_position = layout_manager_->PrimaryAxisValue( |
| 753 view_model_->ideal_bounds(last_button_index).right(), | 796 view_model_->ideal_bounds(last_button_index).right(), |
| 754 view_model_->ideal_bounds(last_button_index).bottom()) | 797 view_model_->ideal_bounds(last_button_index).bottom()) |
| 755 + button_size; | 798 + button_size + inset; |
| 799 if (!ash::switches::UseAlternateShelfLayout()) |
| 800 last_icon_position += button_size; |
| 756 int reserved_icon_space = available_size * kReservedNonPanelIconProportion; | 801 int reserved_icon_space = available_size * kReservedNonPanelIconProportion; |
| 757 if (last_icon_position < reserved_icon_space) | 802 if (last_icon_position < reserved_icon_space) |
| 758 end_position = last_icon_position; | 803 end_position = last_icon_position; |
| 759 else | 804 else |
| 760 end_position = std::max(end_position, reserved_icon_space); | 805 end_position = std::max(end_position, reserved_icon_space); |
| 761 | 806 |
| 762 bounds->overflow_bounds.set_size( | 807 bounds->overflow_bounds.set_size( |
| 763 gfx::Size(layout_manager_->PrimaryAxisValue(w, width()), | 808 gfx::Size(layout_manager_->PrimaryAxisValue(w, width()), |
| 764 layout_manager_->PrimaryAxisValue(height(), h))); | 809 layout_manager_->PrimaryAxisValue(height(), h))); |
| 765 | 810 |
| 766 last_visible_index_ = DetermineLastVisibleIndex( | 811 if (ash::switches::UseAlternateShelfLayout()) { |
| 767 end_position - button_size); | 812 last_visible_index_ = DetermineLastVisibleIndex( |
| 813 end_position - button_size); |
| 814 } else { |
| 815 last_visible_index_ = DetermineLastVisibleIndex( |
| 816 end_position - inset - 2 * button_size); |
| 817 } |
| 768 last_hidden_index_ = DetermineFirstVisiblePanelIndex(end_position) - 1; | 818 last_hidden_index_ = DetermineFirstVisiblePanelIndex(end_position) - 1; |
| 769 bool show_overflow = (last_visible_index_ < last_button_index || | 819 bool show_overflow = |
| 770 last_hidden_index_ >= first_panel_index); | 820 ((ash::switches::UseAlternateShelfLayout() ? 0 : 1) + |
| 821 last_visible_index_ < last_button_index || |
| 822 last_hidden_index_ >= first_panel_index); |
| 771 | 823 |
| 772 // Create Space for the overflow button | 824 // Create Space for the overflow button |
| 773 if (show_overflow && last_visible_index_ > 0 && | 825 if (show_overflow && ash::switches::UseAlternateShelfLayout() && |
| 774 last_visible_index_ < last_button_index) | 826 last_visible_index_ > 0 && last_visible_index_ < last_button_index) |
| 775 --last_visible_index_; | 827 --last_visible_index_; |
| 776 for (int i = 0; i < view_model_->view_size(); ++i) { | 828 for (int i = 0; i < view_model_->view_size(); ++i) { |
| 777 bool visible = i <= last_visible_index_ || i > last_hidden_index_; | 829 bool visible = i <= last_visible_index_ || i > last_hidden_index_; |
| 830 // Always show the app list. |
| 831 if (!ash::switches::UseAlternateShelfLayout()) |
| 832 visible |= (i == last_button_index); |
| 778 // To receive drag event continously from |drag_view_| during the dragging | 833 // To receive drag event continously from |drag_view_| during the dragging |
| 779 // off from the shelf, don't make |drag_view_| invisible. It will be | 834 // off from the shelf, don't make |drag_view_| invisible. It will be |
| 780 // eventually invisible and removed from the |view_model_| by | 835 // eventually invisible and removed from the |view_model_| by |
| 781 // FinalizeRipOffDrag(). | 836 // FinalizeRipOffDrag(). |
| 782 if (dragged_off_shelf_ && view_model_->view_at(i) == drag_view_) | 837 if (dragged_off_shelf_ && view_model_->view_at(i) == drag_view_) |
| 783 continue; | 838 continue; |
| 784 view_model_->view_at(i)->SetVisible(visible); | 839 view_model_->view_at(i)->SetVisible(visible); |
| 785 } | 840 } |
| 786 | 841 |
| 787 overflow_button_->SetVisible(show_overflow); | 842 overflow_button_->SetVisible(show_overflow); |
| 788 if (show_overflow) { | 843 if (show_overflow) { |
| 789 DCHECK_NE(0, view_model_->view_size()); | 844 DCHECK_NE(0, view_model_->view_size()); |
| 790 if (last_visible_index_ == -1) { | 845 if (last_visible_index_ == -1) { |
| 791 x = 0; | 846 x = layout_manager_->SelectValueForShelfAlignment(inset, 0, 0, inset); |
| 792 y = 0; | 847 y = layout_manager_->SelectValueForShelfAlignment(0, inset, inset, 0); |
| 848 } else if (last_visible_index_ == last_button_index |
| 849 && !ash::switches::UseAlternateShelfLayout()) { |
| 850 x = view_model_->ideal_bounds(last_visible_index_).x(); |
| 851 y = view_model_->ideal_bounds(last_visible_index_).y(); |
| 793 } else { | 852 } else { |
| 794 x = layout_manager_->PrimaryAxisValue( | 853 x = layout_manager_->PrimaryAxisValue( |
| 795 view_model_->ideal_bounds(last_visible_index_).right(), | 854 view_model_->ideal_bounds(last_visible_index_).right(), |
| 796 view_model_->ideal_bounds(last_visible_index_).x()); | 855 view_model_->ideal_bounds(last_visible_index_).x()); |
| 797 y = layout_manager_->PrimaryAxisValue( | 856 y = layout_manager_->PrimaryAxisValue( |
| 798 view_model_->ideal_bounds(last_visible_index_).y(), | 857 view_model_->ideal_bounds(last_visible_index_).y(), |
| 799 view_model_->ideal_bounds(last_visible_index_).bottom()); | 858 view_model_->ideal_bounds(last_visible_index_).bottom()); |
| 800 } | 859 } |
| 801 // Set all hidden panel icon positions to be on the overflow button. | 860 // Set all hidden panel icon positions to be on the overflow button. |
| 802 for (int i = first_panel_index; i <= last_hidden_index_; ++i) | 861 for (int i = first_panel_index; i <= last_hidden_index_; ++i) |
| 803 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); | 862 view_model_->set_ideal_bounds(i, gfx::Rect(x, y, w, h)); |
| 804 | 863 |
| 805 // Add more space between last visible item and overflow button. | 864 // Add more space between last visible item and overflow button. |
| 806 // Without this, two buttons look too close compared with other items. | 865 // Without this, two buttons look too close compared with other items. |
| 807 x = layout_manager_->PrimaryAxisValue(x + button_spacing, x); | 866 if (ash::switches::UseAlternateShelfLayout()) { |
| 808 y = layout_manager_->PrimaryAxisValue(y, y + button_spacing); | 867 x = layout_manager_->PrimaryAxisValue(x + button_spacing, x); |
| 868 y = layout_manager_->PrimaryAxisValue(y, y + button_spacing); |
| 869 } |
| 809 | 870 |
| 810 bounds->overflow_bounds.set_x(x); | 871 bounds->overflow_bounds.set_x(x); |
| 811 bounds->overflow_bounds.set_y(y); | 872 bounds->overflow_bounds.set_y(y); |
| 873 if (!ash::switches::UseAlternateShelfLayout()) { |
| 874 // Position app list after overflow button. |
| 875 gfx::Rect app_list_bounds = view_model_->ideal_bounds(last_button_index); |
| 876 |
| 877 x = layout_manager_->PrimaryAxisValue(x + w + button_spacing, x); |
| 878 y = layout_manager_->PrimaryAxisValue(y, y + h + button_spacing); |
| 879 app_list_bounds.set_x(x); |
| 880 app_list_bounds.set_y(y); |
| 881 view_model_->set_ideal_bounds(last_button_index, app_list_bounds); |
| 882 } |
| 812 if (overflow_bubble_.get() && overflow_bubble_->IsShowing()) | 883 if (overflow_bubble_.get() && overflow_bubble_->IsShowing()) |
| 813 UpdateOverflowRange(overflow_bubble_->shelf_view()); | 884 UpdateOverflowRange(overflow_bubble_->shelf_view()); |
| 814 } else { | 885 } else { |
| 815 if (overflow_bubble_) | 886 if (overflow_bubble_) |
| 816 overflow_bubble_->Hide(); | 887 overflow_bubble_->Hide(); |
| 817 } | 888 } |
| 818 } | 889 } |
| 819 | 890 |
| 820 int ShelfView::DetermineLastVisibleIndex(int max_value) const { | 891 int ShelfView::DetermineLastVisibleIndex(int max_value) const { |
| 821 int index = model_->FirstPanelIndex() - 1; | 892 int index = model_->FirstPanelIndex() - 1; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 850 void ShelfView::AnimateToIdealBounds() { | 921 void ShelfView::AnimateToIdealBounds() { |
| 851 IdealBounds ideal_bounds; | 922 IdealBounds ideal_bounds; |
| 852 CalculateIdealBounds(&ideal_bounds); | 923 CalculateIdealBounds(&ideal_bounds); |
| 853 for (int i = 0; i < view_model_->view_size(); ++i) { | 924 for (int i = 0; i < view_model_->view_size(); ++i) { |
| 854 View* view = view_model_->view_at(i); | 925 View* view = view_model_->view_at(i); |
| 855 bounds_animator_->AnimateViewTo(view, view_model_->ideal_bounds(i)); | 926 bounds_animator_->AnimateViewTo(view, view_model_->ideal_bounds(i)); |
| 856 // Now that the item animation starts, we have to make sure that the | 927 // Now that the item animation starts, we have to make sure that the |
| 857 // padding of the first gets properly transferred to the new first item. | 928 // padding of the first gets properly transferred to the new first item. |
| 858 if (i && view->border()) | 929 if (i && view->border()) |
| 859 view->SetBorder(views::Border::NullBorder()); | 930 view->SetBorder(views::Border::NullBorder()); |
| 931 else if (!i && !view->border()) |
| 932 UpdateFirstButtonPadding(); |
| 860 } | 933 } |
| 861 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); | 934 overflow_button_->SetBoundsRect(ideal_bounds.overflow_bounds); |
| 862 } | 935 } |
| 863 | 936 |
| 864 views::View* ShelfView::CreateViewForItem(const ShelfItem& item) { | 937 views::View* ShelfView::CreateViewForItem(const ShelfItem& item) { |
| 865 views::View* view = NULL; | 938 views::View* view = NULL; |
| 866 switch (item.type) { | 939 switch (item.type) { |
| 867 case TYPE_BROWSER_SHORTCUT: | 940 case TYPE_BROWSER_SHORTCUT: |
| 868 case TYPE_APP_SHORTCUT: | 941 case TYPE_APP_SHORTCUT: |
| 869 case TYPE_WINDOWED_APP: | 942 case TYPE_WINDOWED_APP: |
| 870 case TYPE_PLATFORM_APP: | 943 case TYPE_PLATFORM_APP: |
| 871 case TYPE_DIALOG: | 944 case TYPE_DIALOG: |
| 872 case TYPE_APP_PANEL: { | 945 case TYPE_APP_PANEL: { |
| 873 ShelfButton* button = ShelfButton::Create(this, this, layout_manager_); | 946 ShelfButton* button = ShelfButton::Create(this, this, layout_manager_); |
| 874 button->SetImage(item.image); | 947 button->SetImage(item.image); |
| 875 ReflectItemStatus(item, button); | 948 ReflectItemStatus(item, button); |
| 876 view = button; | 949 view = button; |
| 877 break; | 950 break; |
| 878 } | 951 } |
| 879 | 952 |
| 880 case TYPE_APP_LIST: { | 953 case TYPE_APP_LIST: { |
| 881 view = new AppListButton(this, this, layout_manager_->shelf_widget()); | 954 if (ash::switches::UseAlternateShelfLayout()) { |
| 955 view = new AlternateAppListButton(this, |
| 956 this, |
| 957 layout_manager_->shelf_widget()); |
| 958 } else { |
| 959 // TODO(dave): turn this into a ShelfButton too. |
| 960 AppListButton* button = new AppListButton(this, this); |
| 961 button->SetImageAlignment( |
| 962 layout_manager_->SelectValueForShelfAlignment( |
| 963 views::ImageButton::ALIGN_CENTER, |
| 964 views::ImageButton::ALIGN_LEFT, |
| 965 views::ImageButton::ALIGN_RIGHT, |
| 966 views::ImageButton::ALIGN_CENTER), |
| 967 layout_manager_->SelectValueForShelfAlignment( |
| 968 views::ImageButton::ALIGN_TOP, |
| 969 views::ImageButton::ALIGN_MIDDLE, |
| 970 views::ImageButton::ALIGN_MIDDLE, |
| 971 views::ImageButton::ALIGN_BOTTOM)); |
| 972 view = button; |
| 973 } |
| 882 break; | 974 break; |
| 883 } | 975 } |
| 884 | 976 |
| 885 default: | 977 default: |
| 886 break; | 978 break; |
| 887 } | 979 } |
| 888 view->set_context_menu_controller(this); | 980 view->set_context_menu_controller(this); |
| 889 | 981 |
| 890 DCHECK(view); | 982 DCHECK(view); |
| 891 ConfigureChildView(view); | 983 ConfigureChildView(view); |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1228 overflow_view->set_owner_overflow_bubble(overflow_bubble_.get()); | 1320 overflow_view->set_owner_overflow_bubble(overflow_bubble_.get()); |
| 1229 overflow_view->OnShelfAlignmentChanged(); | 1321 overflow_view->OnShelfAlignmentChanged(); |
| 1230 overflow_view->main_shelf_ = this; | 1322 overflow_view->main_shelf_ = this; |
| 1231 UpdateOverflowRange(overflow_view); | 1323 UpdateOverflowRange(overflow_view); |
| 1232 | 1324 |
| 1233 overflow_bubble_->Show(overflow_button_, overflow_view); | 1325 overflow_bubble_->Show(overflow_button_, overflow_view); |
| 1234 | 1326 |
| 1235 Shell::GetInstance()->UpdateShelfVisibility(); | 1327 Shell::GetInstance()->UpdateShelfVisibility(); |
| 1236 } | 1328 } |
| 1237 | 1329 |
| 1330 void ShelfView::UpdateFirstButtonPadding() { |
| 1331 if (ash::switches::UseAlternateShelfLayout()) |
| 1332 return; |
| 1333 |
| 1334 // Creates an empty border for first shelf button to make included leading |
| 1335 // inset act as the button's padding. This is only needed on button creation |
| 1336 // and when shelf alignment changes. |
| 1337 if (view_model_->view_size() > 0) { |
| 1338 view_model_->view_at(0)->SetBorder(views::Border::CreateEmptyBorder( |
| 1339 layout_manager_->PrimaryAxisValue(0, leading_inset_), |
| 1340 layout_manager_->PrimaryAxisValue(leading_inset_, 0), |
| 1341 0, |
| 1342 0)); |
| 1343 } |
| 1344 } |
| 1345 |
| 1238 void ShelfView::OnFadeOutAnimationEnded() { | 1346 void ShelfView::OnFadeOutAnimationEnded() { |
| 1239 AnimateToIdealBounds(); | 1347 AnimateToIdealBounds(); |
| 1240 StartFadeInLastVisibleItem(); | 1348 StartFadeInLastVisibleItem(); |
| 1241 } | 1349 } |
| 1242 | 1350 |
| 1243 void ShelfView::StartFadeInLastVisibleItem() { | 1351 void ShelfView::StartFadeInLastVisibleItem() { |
| 1244 // If overflow button is visible and there is a valid new last item, fading | 1352 // If overflow button is visible and there is a valid new last item, fading |
| 1245 // the new last item in after sliding animation is finished. | 1353 // the new last item in after sliding animation is finished. |
| 1246 if (overflow_button_->visible() && last_visible_index_ >= 0) { | 1354 if (overflow_button_->visible() && last_visible_index_ >= 0) { |
| 1247 views::View* last_visible_view = view_model_->view_at(last_visible_index_); | 1355 views::View* last_visible_view = view_model_->view_at(last_visible_index_); |
| 1248 last_visible_view->layer()->SetOpacity(0); | 1356 last_visible_view->layer()->SetOpacity(0); |
| 1249 bounds_animator_->SetAnimationDelegate( | 1357 bounds_animator_->SetAnimationDelegate( |
| 1250 last_visible_view, | 1358 last_visible_view, |
| 1251 new ShelfView::StartFadeAnimationDelegate(this, last_visible_view), | 1359 new ShelfView::StartFadeAnimationDelegate(this, last_visible_view), |
| 1252 true); | 1360 true); |
| 1253 } | 1361 } |
| 1254 } | 1362 } |
| 1255 | 1363 |
| 1256 void ShelfView::UpdateOverflowRange(ShelfView* overflow_view) { | 1364 void ShelfView::UpdateOverflowRange(ShelfView* overflow_view) { |
| 1257 const int first_overflow_index = last_visible_index_ + 1; | 1365 const int first_overflow_index = last_visible_index_ + 1; |
| 1258 const int last_overflow_index = last_hidden_index_; | 1366 const int last_overflow_index = last_hidden_index_; |
| 1259 DCHECK_LE(first_overflow_index, last_overflow_index); | 1367 DCHECK_LE(first_overflow_index, last_overflow_index); |
| 1260 DCHECK_LT(last_overflow_index, view_model_->view_size()); | 1368 DCHECK_LT(last_overflow_index, view_model_->view_size()); |
| 1261 | 1369 |
| 1262 overflow_view->first_visible_index_ = first_overflow_index; | 1370 overflow_view->first_visible_index_ = first_overflow_index; |
| 1263 overflow_view->last_visible_index_ = last_overflow_index; | 1371 overflow_view->last_visible_index_ = last_overflow_index; |
| 1264 } | 1372 } |
| 1265 | 1373 |
| 1374 int ShelfView::GetButtonSize() const { |
| 1375 return ash::switches::UseAlternateShelfLayout() ? |
| 1376 kButtonSize : kShelfPreferredSize; |
| 1377 } |
| 1378 |
| 1379 int ShelfView::GetButtonSpacing() const { |
| 1380 return ash::switches::UseAlternateShelfLayout() ? |
| 1381 kAlternateButtonSpacing : kButtonSpacing; |
| 1382 } |
| 1383 |
| 1266 bool ShelfView::ShouldHideTooltip(const gfx::Point& cursor_location) { | 1384 bool ShelfView::ShouldHideTooltip(const gfx::Point& cursor_location) { |
| 1267 gfx::Rect active_bounds; | 1385 gfx::Rect active_bounds; |
| 1268 | 1386 |
| 1269 for (int i = 0; i < child_count(); ++i) { | 1387 for (int i = 0; i < child_count(); ++i) { |
| 1270 views::View* child = child_at(i); | 1388 views::View* child = child_at(i); |
| 1271 if (child == overflow_button_) | 1389 if (child == overflow_button_) |
| 1272 continue; | 1390 continue; |
| 1273 if (!ShouldShowTooltipForView(child)) | 1391 if (!ShouldShowTooltipForView(child)) |
| 1274 continue; | 1392 continue; |
| 1275 | 1393 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1288 } | 1406 } |
| 1289 | 1407 |
| 1290 gfx::Rect ShelfView::GetBoundsForDragInsertInScreen() { | 1408 gfx::Rect ShelfView::GetBoundsForDragInsertInScreen() { |
| 1291 gfx::Size preferred_size; | 1409 gfx::Size preferred_size; |
| 1292 if (is_overflow_mode()) { | 1410 if (is_overflow_mode()) { |
| 1293 DCHECK(owner_overflow_bubble_); | 1411 DCHECK(owner_overflow_bubble_); |
| 1294 gfx::Rect bubble_bounds = | 1412 gfx::Rect bubble_bounds = |
| 1295 owner_overflow_bubble_->bubble_view()->GetBubbleBounds(); | 1413 owner_overflow_bubble_->bubble_view()->GetBubbleBounds(); |
| 1296 preferred_size = bubble_bounds.size(); | 1414 preferred_size = bubble_bounds.size(); |
| 1297 } else { | 1415 } else { |
| 1416 const int preferred_shelf_size = layout_manager_->GetPreferredShelfSize(); |
| 1417 |
| 1298 const int last_button_index = view_model_->view_size() - 1; | 1418 const int last_button_index = view_model_->view_size() - 1; |
| 1299 gfx::Rect last_button_bounds = | 1419 gfx::Rect last_button_bounds = |
| 1300 view_model_->view_at(last_button_index)->bounds(); | 1420 view_model_->view_at(last_button_index)->bounds(); |
| 1301 if (overflow_button_->visible() && | 1421 if (overflow_button_->visible() && |
| 1302 model_->GetItemIndexForType(TYPE_APP_PANEL) == -1) { | 1422 model_->GetItemIndexForType(TYPE_APP_PANEL) == -1) { |
| 1303 // When overflow button is visible and shelf has no panel items, | 1423 // When overflow button is visible and shelf has no panel items, |
| 1304 // last_button_bounds should be overflow button's bounds. | 1424 // last_button_bounds should be overflow button's bounds. |
| 1305 last_button_bounds = overflow_button_->bounds(); | 1425 last_button_bounds = overflow_button_->bounds(); |
| 1306 } | 1426 } |
| 1307 | 1427 |
| 1308 if (layout_manager_->IsHorizontalAlignment()) { | 1428 if (layout_manager_->IsHorizontalAlignment()) { |
| 1309 preferred_size = gfx::Size(last_button_bounds.right() + leading_inset_, | 1429 preferred_size = gfx::Size(last_button_bounds.right() + leading_inset_, |
| 1310 kShelfSize); | 1430 preferred_shelf_size); |
| 1311 } else { | 1431 } else { |
| 1312 preferred_size = gfx::Size(kShelfSize, | 1432 preferred_size = gfx::Size(preferred_shelf_size, |
| 1313 last_button_bounds.bottom() + leading_inset_); | 1433 last_button_bounds.bottom() + leading_inset_); |
| 1314 } | 1434 } |
| 1315 } | 1435 } |
| 1316 gfx::Point origin(GetMirroredXWithWidthInView(0, preferred_size.width()), 0); | 1436 gfx::Point origin(GetMirroredXWithWidthInView(0, preferred_size.width()), 0); |
| 1317 | 1437 |
| 1318 // In overflow mode, we should use OverflowBubbleView as a source for | 1438 // In overflow mode, we should use OverflowBubbleView as a source for |
| 1319 // converting |origin| to screen coordinates. When a scroll operation is | 1439 // converting |origin| to screen coordinates. When a scroll operation is |
| 1320 // occurred in OverflowBubble, the bounds of ShelfView in OverflowBubble can | 1440 // occurred in OverflowBubble, the bounds of ShelfView in OverflowBubble can |
| 1321 // be changed. | 1441 // be changed. |
| 1322 if (is_overflow_mode()) | 1442 if (is_overflow_mode()) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1353 // the list. | 1473 // the list. |
| 1354 if (at_end) | 1474 if (at_end) |
| 1355 return view_model_->view_size(); | 1475 return view_model_->view_size(); |
| 1356 return modified_view ? view_model_->GetIndexOfView(modified_view) : -1; | 1476 return modified_view ? view_model_->GetIndexOfView(modified_view) : -1; |
| 1357 } | 1477 } |
| 1358 | 1478 |
| 1359 gfx::Size ShelfView::GetPreferredSize() { | 1479 gfx::Size ShelfView::GetPreferredSize() { |
| 1360 IdealBounds ideal_bounds; | 1480 IdealBounds ideal_bounds; |
| 1361 CalculateIdealBounds(&ideal_bounds); | 1481 CalculateIdealBounds(&ideal_bounds); |
| 1362 | 1482 |
| 1483 const int preferred_size = layout_manager_->GetPreferredShelfSize(); |
| 1484 |
| 1363 int last_button_index = is_overflow_mode() ? | 1485 int last_button_index = is_overflow_mode() ? |
| 1364 last_visible_index_ : view_model_->view_size() - 1; | 1486 last_visible_index_ : view_model_->view_size() - 1; |
| 1365 | 1487 |
| 1366 // When an item is dragged off from the overflow bubble, it is moved to last | 1488 // When an item is dragged off from the overflow bubble, it is moved to last |
| 1367 // position and and changed to invisible. Overflow bubble size should be | 1489 // position and and changed to invisible. Overflow bubble size should be |
| 1368 // shrunk to fit only for visible items. | 1490 // shrunk to fit only for visible items. |
| 1369 // If |dragged_off_from_overflow_to_shelf_| is set, there will be no invisible | 1491 // If |dragged_off_from_overflow_to_shelf_| is set, there will be no invisible |
| 1370 // items in the shelf. | 1492 // items in the shelf. |
| 1371 if (is_overflow_mode() && | 1493 if (is_overflow_mode() && |
| 1372 dragged_off_shelf_ && | 1494 dragged_off_shelf_ && |
| 1373 !dragged_off_from_overflow_to_shelf_ && | 1495 !dragged_off_from_overflow_to_shelf_ && |
| 1374 RemovableByRipOff(view_model_->GetIndexOfView(drag_view_)) == REMOVABLE) | 1496 RemovableByRipOff(view_model_->GetIndexOfView(drag_view_)) == REMOVABLE) |
| 1375 last_button_index--; | 1497 last_button_index--; |
| 1376 | 1498 |
| 1377 const gfx::Rect last_button_bounds = | 1499 const gfx::Rect last_button_bounds = |
| 1378 last_button_index >= first_visible_index_ ? | 1500 last_button_index >= first_visible_index_ ? |
| 1379 view_model_->ideal_bounds(last_button_index) : | 1501 view_model_->ideal_bounds(last_button_index) : |
| 1380 gfx::Rect(gfx::Size(kShelfSize, kShelfSize)); | 1502 gfx::Rect(gfx::Size(preferred_size, preferred_size)); |
| 1381 | 1503 |
| 1382 if (layout_manager_->IsHorizontalAlignment()) { | 1504 if (layout_manager_->IsHorizontalAlignment()) { |
| 1383 return gfx::Size(last_button_bounds.right() + leading_inset_, kShelfSize); | 1505 return gfx::Size(last_button_bounds.right() + leading_inset_, |
| 1506 preferred_size); |
| 1384 } | 1507 } |
| 1385 | 1508 |
| 1386 return gfx::Size(kShelfSize, | 1509 return gfx::Size(preferred_size, |
| 1387 last_button_bounds.bottom() + leading_inset_); | 1510 last_button_bounds.bottom() + leading_inset_); |
| 1388 } | 1511 } |
| 1389 | 1512 |
| 1390 void ShelfView::OnBoundsChanged(const gfx::Rect& previous_bounds) { | 1513 void ShelfView::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
| 1391 // This bounds change is produced by the shelf movement and all content has | 1514 // This bounds change is produced by the shelf movement and all content has |
| 1392 // to follow. Using an animation at that time would produce a time lag since | 1515 // to follow. Using an animation at that time would produce a time lag since |
| 1393 // the animation of the BoundsAnimator has itself a delay before it arrives | 1516 // the animation of the BoundsAnimator has itself a delay before it arrives |
| 1394 // at the required location. As such we tell the animator to go there | 1517 // at the required location. As such we tell the animator to go there |
| 1395 // immediately. | 1518 // immediately. |
| 1396 BoundsAnimatorDisabler disabler(bounds_animator_.get()); | 1519 BoundsAnimatorDisabler disabler(bounds_animator_.get()); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 view_model_->Move(start_index, target_index); | 1664 view_model_->Move(start_index, target_index); |
| 1542 // When cancelling a drag due to a shelf item being added, the currently | 1665 // When cancelling a drag due to a shelf item being added, the currently |
| 1543 // dragged item is moved back to its initial position. AnimateToIdealBounds | 1666 // dragged item is moved back to its initial position. AnimateToIdealBounds |
| 1544 // will be called again when the new item is added to the |view_model_| but | 1667 // will be called again when the new item is added to the |view_model_| but |
| 1545 // at this time the |view_model_| is inconsistent with the |model_|. | 1668 // at this time the |view_model_| is inconsistent with the |model_|. |
| 1546 if (!cancelling_drag_model_changed_) | 1669 if (!cancelling_drag_model_changed_) |
| 1547 AnimateToIdealBounds(); | 1670 AnimateToIdealBounds(); |
| 1548 } | 1671 } |
| 1549 | 1672 |
| 1550 void ShelfView::ShelfStatusChanged() { | 1673 void ShelfView::ShelfStatusChanged() { |
| 1551 // Nothing to do here. | 1674 if (ash::switches::UseAlternateShelfLayout()) |
| 1675 return; |
| 1676 AppListButton* app_list_button = |
| 1677 static_cast<AppListButton*>(GetAppListButtonView()); |
| 1678 if (model_->status() == ShelfModel::STATUS_LOADING) |
| 1679 app_list_button->StartLoadingAnimation(); |
| 1680 else |
| 1681 app_list_button->StopLoadingAnimation(); |
| 1552 } | 1682 } |
| 1553 | 1683 |
| 1554 void ShelfView::PointerPressedOnButton(views::View* view, | 1684 void ShelfView::PointerPressedOnButton(views::View* view, |
| 1555 Pointer pointer, | 1685 Pointer pointer, |
| 1556 const ui::LocatedEvent& event) { | 1686 const ui::LocatedEvent& event) { |
| 1557 if (drag_view_) | 1687 if (drag_view_) |
| 1558 return; | 1688 return; |
| 1559 | 1689 |
| 1560 int index = view_model_->GetIndexOfView(view); | 1690 int index = view_model_->GetIndexOfView(view); |
| 1561 if (index == -1) | 1691 if (index == -1) |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1918 break; | 2048 break; |
| 1919 case SHELF_ALIGNMENT_TOP: | 2049 case SHELF_ALIGNMENT_TOP: |
| 1920 distance = coordinate.y() - bounds.bottom(); | 2050 distance = coordinate.y() - bounds.bottom(); |
| 1921 break; | 2051 break; |
| 1922 } | 2052 } |
| 1923 return distance > 0 ? distance : 0; | 2053 return distance > 0 ? distance : 0; |
| 1924 } | 2054 } |
| 1925 | 2055 |
| 1926 } // namespace internal | 2056 } // namespace internal |
| 1927 } // namespace ash | 2057 } // namespace ash |
| OLD | NEW |