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 "ui/app_list/views/app_list_view.h" | 5 #include "ui/app_list/views/app_list_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 | 54 |
55 // The margin from the edge to the speech UI. | 55 // The margin from the edge to the speech UI. |
56 constexpr int kSpeechUIMargin = 12; | 56 constexpr int kSpeechUIMargin = 12; |
57 | 57 |
58 // The height/width of the shelf. | 58 // The height/width of the shelf. |
59 constexpr int kShelfSize = 48; | 59 constexpr int kShelfSize = 48; |
60 | 60 |
61 // The height of the peeking app list. | 61 // The height of the peeking app list. |
62 constexpr int kPeekingAppListHeight = 320; | 62 constexpr int kPeekingAppListHeight = 320; |
63 | 63 |
| 64 // The height of the half app list. |
| 65 constexpr int kHalfAppListHeight = 561; |
| 66 |
64 // The fraction of app list height that the app list must be released at in | 67 // The fraction of app list height that the app list must be released at in |
65 // order to transition to the next state. | 68 // order to transition to the next state. |
66 constexpr int kAppListThresholdDenominator = 3; | 69 constexpr int kAppListThresholdDenominator = 3; |
67 | 70 |
68 // The velocity the app list must be dragged in order to transition to the next | 71 // The velocity the app list must be dragged in order to transition to the next |
69 // state, measured in DIPs/event. | 72 // state, measured in DIPs/event. |
70 constexpr int kAppListDragVelocityThreshold = 25; | 73 constexpr int kAppListDragVelocityThreshold = 25; |
71 | 74 |
| 75 // The DIP distance from the bezel that a drag event must end within to transfer |
| 76 // the |app_list_state_|. |
| 77 constexpr int kAppListBezelMargin = 50; |
| 78 |
72 // The opacity of the app list background. | 79 // The opacity of the app list background. |
73 constexpr float kAppListOpacity = 0.8; | 80 constexpr float kAppListOpacity = 0.8; |
74 | 81 |
75 // The vertical position for the appearing animation of the speech UI. | 82 // The vertical position for the appearing animation of the speech UI. |
76 constexpr float kSpeechUIAppearingPosition = 12; | 83 constexpr float kSpeechUIAppearingPosition = 12; |
77 | 84 |
78 bool IsFullscreenAppListEnabled() { | 85 bool IsFullscreenAppListEnabled() { |
79 // Cache this value to avoid repeated lookup. | 86 // Cache this value to avoid repeated lookup. |
80 static bool cached_value = features::IsFullscreenAppListEnabled(); | 87 static bool cached_value = features::IsFullscreenAppListEnabled(); |
81 return cached_value; | 88 return cached_value; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 display_observer_.Add(display::Screen::GetScreen()); | 216 display_observer_.Add(display::Screen::GetScreen()); |
210 } | 217 } |
211 | 218 |
212 AppListView::~AppListView() { | 219 AppListView::~AppListView() { |
213 delegate_->GetSpeechUI()->RemoveObserver(this); | 220 delegate_->GetSpeechUI()->RemoveObserver(this); |
214 animation_observer_.reset(); | 221 animation_observer_.reset(); |
215 // Remove child views first to ensure no remaining dependencies on delegate_. | 222 // Remove child views first to ensure no remaining dependencies on delegate_. |
216 RemoveAllChildViews(true); | 223 RemoveAllChildViews(true); |
217 } | 224 } |
218 | 225 |
219 void AppListView::Initialize(gfx::NativeView parent, int initial_apps_page) { | 226 void AppListView::Initialize(gfx::NativeView parent, |
| 227 int initial_apps_page, |
| 228 bool is_maximize_mode, |
| 229 bool is_side_shelf) { |
220 base::Time start_time = base::Time::Now(); | 230 base::Time start_time = base::Time::Now(); |
| 231 is_maximize_mode_ = is_maximize_mode; |
| 232 is_side_shelf_ = is_side_shelf; |
221 InitContents(parent, initial_apps_page); | 233 InitContents(parent, initial_apps_page); |
222 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); | 234 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); |
223 set_color(kContentsBackgroundColor); | 235 set_color(kContentsBackgroundColor); |
224 set_parent_window(parent); | 236 set_parent_window(parent); |
225 | 237 |
226 if (IsFullscreenAppListEnabled()) | 238 if (features::IsFullscreenAppListEnabled()) |
227 InitializeFullscreen(parent, initial_apps_page); | 239 InitializeFullscreen(parent, initial_apps_page); |
228 else | 240 else |
229 InitializeBubble(parent, initial_apps_page); | 241 InitializeBubble(parent, initial_apps_page); |
230 | 242 |
231 InitChildWidgets(); | 243 InitChildWidgets(); |
232 AddChildView(overlay_view_); | 244 AddChildView(overlay_view_); |
233 | 245 |
234 if (IsFullscreenAppListEnabled()) | 246 if (IsFullscreenAppListEnabled()) |
235 SetState(app_list_state_); | 247 SetState(app_list_state_); |
236 | 248 |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 | 523 |
512 void AppListView::EndDrag(const gfx::Point& location) { | 524 void AppListView::EndDrag(const gfx::Point& location) { |
513 // Change the app list state based on where the drag ended. If fling velocity | 525 // Change the app list state based on where the drag ended. If fling velocity |
514 // was over the threshold, snap to the next state in the direction of the | 526 // was over the threshold, snap to the next state in the direction of the |
515 // fling. | 527 // fling. |
516 int const new_y_position = location.y() - initial_drag_point_.y() + | 528 int const new_y_position = location.y() - initial_drag_point_.y() + |
517 fullscreen_widget_->GetWindowBoundsInScreen().y(); | 529 fullscreen_widget_->GetWindowBoundsInScreen().y(); |
518 if (std::abs(last_fling_velocity_) > kAppListDragVelocityThreshold) { | 530 if (std::abs(last_fling_velocity_) > kAppListDragVelocityThreshold) { |
519 // If the user releases drag with velocity over the threshold, snap to | 531 // If the user releases drag with velocity over the threshold, snap to |
520 // the next state, ignoring the drag release position. | 532 // the next state, ignoring the drag release position. |
521 if (app_list_state_ == FULLSCREEN) { | |
522 if (last_fling_velocity_ > 0) | |
523 SetState(PEEKING); | |
524 | 533 |
| 534 if (last_fling_velocity_ > 0) { |
| 535 switch (app_list_state_) { |
| 536 case PEEKING: |
| 537 case HALF: |
| 538 case FULLSCREEN_SEARCH: |
| 539 SetState(CLOSED); |
| 540 break; |
| 541 case FULLSCREEN_ALL_APPS: |
| 542 SetState(is_maximize_mode_ || is_side_shelf_ ? CLOSED : PEEKING); |
| 543 break; |
| 544 case CLOSED: |
| 545 NOTREACHED(); |
| 546 break; |
| 547 } |
525 } else { | 548 } else { |
526 SetState(last_fling_velocity_ > 0 ? CLOSED : FULLSCREEN); | 549 switch (app_list_state_) { |
| 550 case FULLSCREEN_ALL_APPS: |
| 551 case FULLSCREEN_SEARCH: |
| 552 SetState(app_list_state_); |
| 553 break; |
| 554 case HALF: |
| 555 SetState(FULLSCREEN_SEARCH); |
| 556 break; |
| 557 case PEEKING: |
| 558 SetState(FULLSCREEN_ALL_APPS); |
| 559 break; |
| 560 case CLOSED: |
| 561 NOTREACHED(); |
| 562 break; |
| 563 } |
527 } | 564 } |
528 last_fling_velocity_ = 0; | |
529 } else { | 565 } else { |
530 int display_height = display::Screen::GetScreen() | 566 int display_height = display::Screen::GetScreen() |
531 ->GetDisplayNearestView(parent_window()) | 567 ->GetDisplayNearestView(parent_window()) |
532 .work_area() | 568 .work_area() |
533 .height(); | 569 .height(); |
534 int default_peeking_y = display_height + kShelfSize - kPeekingAppListHeight; | 570 int app_list_y_for_state = 0; |
535 // The drag release velocity was too low, so use the release point. | 571 int app_list_height = 0; |
536 int app_list_snap_y = | 572 switch (app_list_state_) { |
537 (app_list_state_ == FULLSCREEN) ? 0 : default_peeking_y; | 573 case FULLSCREEN_ALL_APPS: |
538 // The DIP delta that must be exceeded for the app list to snap to the next | 574 case FULLSCREEN_SEARCH: |
539 // state. | 575 app_list_y_for_state = 0; |
540 int app_list_threshold = | 576 app_list_height = display_height; |
541 (fullscreen_widget_->GetWindowBoundsInScreen().height() + kShelfSize) / | 577 break; |
542 kAppListThresholdDenominator; | 578 case HALF: |
543 app_list_threshold -= | 579 app_list_y_for_state = display_height - kHalfAppListHeight; |
544 (app_list_state_ == FULLSCREEN ? 0 : kPeekingAppListHeight) / | 580 app_list_height = kHalfAppListHeight; |
545 kAppListThresholdDenominator; | 581 break; |
| 582 case PEEKING: |
| 583 app_list_y_for_state = display_height - kPeekingAppListHeight; |
| 584 app_list_height = kPeekingAppListHeight; |
| 585 break; |
| 586 case CLOSED: |
| 587 NOTREACHED(); |
| 588 break; |
| 589 } |
546 | 590 |
547 // If the user releases +/- 1/3 of |app_list_threshold|, snap to the | 591 int app_list_threshold = app_list_height / kAppListThresholdDenominator; |
548 // next state. | 592 int drag_delta = app_list_y_for_state - new_y_position; |
549 if (std::abs(app_list_snap_y - new_y_position) < app_list_threshold) { | 593 switch (app_list_state_) { |
550 // The drag was not far enough so set the app list bounds to the target | 594 case FULLSCREEN_ALL_APPS: |
551 // bounds for the current state. | 595 if (std::abs(drag_delta) > app_list_threshold) |
552 SetState(app_list_state_); | 596 SetState(is_maximize_mode_ || is_side_shelf_ ? CLOSED : PEEKING); |
553 } else if ((app_list_snap_y + app_list_threshold) < new_y_position) { | 597 else |
554 // The drag was far enough to change states and was a downward drag, so | 598 SetState(app_list_state_); |
555 // set the app list bounds to the next state. | 599 break; |
556 SetState(app_list_state_ == FULLSCREEN ? PEEKING : CLOSED); | 600 case FULLSCREEN_SEARCH: |
557 } else { | 601 if (std::abs(drag_delta) > app_list_threshold) |
558 // The drag was far enough to change states and was an upward drag, so | 602 SetState(CLOSED); |
559 // set the app list bounds to the next state. | 603 else |
560 SetState(FULLSCREEN); | 604 SetState(app_list_state_); |
| 605 break; |
| 606 case HALF: |
| 607 if (std::abs(drag_delta) > app_list_threshold) { |
| 608 SetState(drag_delta > 0 ? FULLSCREEN_SEARCH : CLOSED); |
| 609 } else if (location.y() + |
| 610 fullscreen_widget_->GetWindowBoundsInScreen().y() >= |
| 611 display_height - kAppListBezelMargin) { |
| 612 // If the user drags to the bezel, close the app list. |
| 613 SetState(CLOSED); |
| 614 } else { |
| 615 SetState(app_list_state_); |
| 616 } |
| 617 break; |
| 618 case PEEKING: |
| 619 if (std::abs(drag_delta) > app_list_threshold) { |
| 620 SetState(drag_delta > 0 ? FULLSCREEN_ALL_APPS : CLOSED); |
| 621 } else if (location.y() + |
| 622 fullscreen_widget_->GetWindowBoundsInScreen().y() >= |
| 623 display_height - kAppListBezelMargin) { |
| 624 // If the user drags to the bezel, close the app list. |
| 625 SetState(CLOSED); |
| 626 } else { |
| 627 SetState(app_list_state_); |
| 628 } |
| 629 break; |
| 630 case CLOSED: |
| 631 NOTREACHED(); |
| 632 break; |
561 } | 633 } |
562 } | 634 } |
563 } | 635 } |
564 | 636 |
| 637 void AppListView::SetStateFromSearchBoxView(bool search_box_is_empty) { |
| 638 switch (app_list_state_) { |
| 639 case PEEKING: |
| 640 if (!search_box_is_empty) |
| 641 SetState(HALF); |
| 642 break; |
| 643 case HALF: |
| 644 if (search_box_is_empty) |
| 645 SetState(PEEKING); |
| 646 break; |
| 647 case FULLSCREEN_SEARCH: |
| 648 if (search_box_is_empty) { |
| 649 SetState(FULLSCREEN_ALL_APPS); |
| 650 app_list_main_view()->contents_view()->SetActiveState( |
| 651 AppListModel::State::STATE_APPS); |
| 652 } |
| 653 break; |
| 654 case FULLSCREEN_ALL_APPS: |
| 655 if (!search_box_is_empty) |
| 656 SetState(FULLSCREEN_SEARCH); |
| 657 break; |
| 658 case CLOSED: |
| 659 NOTREACHED(); |
| 660 break; |
| 661 } |
| 662 } |
| 663 |
| 664 void AppListView::OnMaximizeModeChanged(bool started) { |
| 665 is_maximize_mode_ = started; |
| 666 if (is_maximize_mode_ && !is_fullscreen()) { |
| 667 // Set |app_list_state_| to a maximize mode friendly state. |
| 668 SetState(app_list_state_ == PEEKING ? FULLSCREEN_ALL_APPS |
| 669 : FULLSCREEN_SEARCH); |
| 670 } |
| 671 } |
| 672 |
565 void AppListView::OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, | 673 void AppListView::OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, |
566 views::Widget* widget) const { | 674 views::Widget* widget) const { |
567 if (!params->native_widget) { | 675 if (!params->native_widget) { |
568 views::ViewsDelegate* views_delegate = views::ViewsDelegate::GetInstance(); | 676 views::ViewsDelegate* views_delegate = views::ViewsDelegate::GetInstance(); |
569 if (views_delegate && !views_delegate->native_widget_factory().is_null()) { | 677 if (views_delegate && !views_delegate->native_widget_factory().is_null()) { |
570 params->native_widget = | 678 params->native_widget = |
571 views_delegate->native_widget_factory().Run(*params, widget); | 679 views_delegate->native_widget_factory().Run(*params, widget); |
572 } | 680 } |
573 } | 681 } |
574 // Apply a WM-provided shadow (see ui/wm/core/). | 682 // Apply a WM-provided shadow (see ui/wm/core/). |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 } | 795 } |
688 } | 796 } |
689 | 797 |
690 void AppListView::SchedulePaintInRect(const gfx::Rect& rect) { | 798 void AppListView::SchedulePaintInRect(const gfx::Rect& rect) { |
691 BubbleDialogDelegateView::SchedulePaintInRect(rect); | 799 BubbleDialogDelegateView::SchedulePaintInRect(rect); |
692 if (GetBubbleFrameView()) | 800 if (GetBubbleFrameView()) |
693 GetBubbleFrameView()->SchedulePaint(); | 801 GetBubbleFrameView()->SchedulePaint(); |
694 } | 802 } |
695 | 803 |
696 void AppListView::SetState(AppListState new_state) { | 804 void AppListView::SetState(AppListState new_state) { |
| 805 AppListState new_state_override = new_state; |
| 806 if (is_side_shelf_ || is_maximize_mode_) { |
| 807 // If side shelf or maximize mode are active, all transitions should be |
| 808 // made to the maximize mode/side shelf friendly versions. |
| 809 if (new_state == PEEKING) |
| 810 new_state_override = FULLSCREEN_ALL_APPS; |
| 811 else if (new_state == HALF) |
| 812 new_state_override = FULLSCREEN_SEARCH; |
| 813 } |
| 814 |
697 gfx::Rect new_widget_bounds = fullscreen_widget_->GetWindowBoundsInScreen(); | 815 gfx::Rect new_widget_bounds = fullscreen_widget_->GetWindowBoundsInScreen(); |
698 switch (new_state) { | 816 int display_height = display::Screen::GetScreen() |
| 817 ->GetDisplayNearestView(parent_window()) |
| 818 .work_area() |
| 819 .bottom(); |
| 820 |
| 821 switch (new_state_override) { |
699 case PEEKING: { | 822 case PEEKING: { |
700 int display_height = display::Screen::GetScreen() | 823 switch (app_list_state_) { |
701 ->GetDisplayNearestView(parent_window()) | 824 case HALF: |
702 .work_area() | 825 case FULLSCREEN_ALL_APPS: |
703 .bottom(); | 826 case PEEKING: { |
704 int default_peeking_y = | 827 int peeking_app_list_y = display_height - kPeekingAppListHeight; |
705 display_height + kShelfSize - kPeekingAppListHeight; | 828 new_widget_bounds.set_y(peeking_app_list_y); |
706 new_widget_bounds.set_y(default_peeking_y); | 829 app_list_main_view_->contents_view()->SetActiveState( |
| 830 AppListModel::STATE_START); |
| 831 break; |
| 832 } |
| 833 case FULLSCREEN_SEARCH: |
| 834 case CLOSED: |
| 835 NOTREACHED(); |
| 836 break; |
| 837 } |
| 838 } break; |
| 839 case HALF: |
| 840 switch (app_list_state_) { |
| 841 case PEEKING: |
| 842 case HALF: { |
| 843 int half_app_list_y = display_height - kHalfAppListHeight; |
| 844 new_widget_bounds.set_y(half_app_list_y); |
| 845 break; |
| 846 } |
| 847 case FULLSCREEN_SEARCH: |
| 848 case FULLSCREEN_ALL_APPS: |
| 849 case CLOSED: |
| 850 NOTREACHED(); |
| 851 break; |
| 852 } |
707 break; | 853 break; |
708 } | 854 case FULLSCREEN_ALL_APPS: |
709 case FULLSCREEN: | 855 new_widget_bounds.set_y(0); |
| 856 app_list_main_view_->contents_view()->SetActiveState( |
| 857 AppListModel::STATE_APPS); |
| 858 break; |
| 859 case FULLSCREEN_SEARCH: |
710 new_widget_bounds.set_y(0); | 860 new_widget_bounds.set_y(0); |
711 break; | 861 break; |
712 case CLOSED: | 862 case CLOSED: |
713 app_list_main_view_->Close(); | 863 app_list_main_view_->Close(); |
714 delegate_->Dismiss(); | 864 delegate_->Dismiss(); |
715 break; | 865 break; |
716 } | 866 } |
717 fullscreen_widget_->SetBounds(new_widget_bounds); | 867 fullscreen_widget_->SetBounds(new_widget_bounds); |
718 app_list_state_ = new_state; | 868 app_list_state_ = new_state_override; |
719 } | 869 } |
720 | 870 |
721 void AppListView::OnWidgetDestroying(views::Widget* widget) { | 871 void AppListView::OnWidgetDestroying(views::Widget* widget) { |
722 BubbleDialogDelegateView::OnWidgetDestroying(widget); | 872 BubbleDialogDelegateView::OnWidgetDestroying(widget); |
723 if (delegate_ && widget == GetWidget()) | 873 if (delegate_ && widget == GetWidget()) |
724 delegate_->ViewClosing(); | 874 delegate_->ViewClosing(); |
725 } | 875 } |
726 | 876 |
727 void AppListView::OnWidgetVisibilityChanged(views::Widget* widget, | 877 void AppListView::OnWidgetVisibilityChanged(views::Widget* widget, |
728 bool visible) { | 878 bool visible) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 .work_area() | 963 .work_area() |
814 .size(); | 964 .size(); |
815 size.Enlarge(0, kShelfSize); | 965 size.Enlarge(0, kShelfSize); |
816 fullscreen_widget_->SetSize(size); | 966 fullscreen_widget_->SetSize(size); |
817 | 967 |
818 // Update the |fullscreen_widget_| bounds to accomodate the new work area. | 968 // Update the |fullscreen_widget_| bounds to accomodate the new work area. |
819 SetState(app_list_state_); | 969 SetState(app_list_state_); |
820 } | 970 } |
821 | 971 |
822 } // namespace app_list | 972 } // namespace app_list |
OLD | NEW |