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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 #include "ui/wm/core/masked_window_targeter.h" | 48 #include "ui/wm/core/masked_window_targeter.h" |
49 #include "ui/wm/core/shadow_types.h" | 49 #include "ui/wm/core/shadow_types.h" |
50 | 50 |
51 namespace app_list { | 51 namespace app_list { |
52 | 52 |
53 namespace { | 53 namespace { |
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 from the bottom/side of the screen. |
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 from the bottom of the screen. |
62 constexpr int kPeekingAppListHeight = 320; | 62 constexpr int kPeekingAppListHeight = 320; |
63 | 63 |
| 64 // The height of the half app list from the bottom of the screen. |
| 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 // This view forwards the focus to the search box widget by providing it as a | 85 // This view forwards the focus to the search box widget by providing it as a |
79 // FocusTraversable when a focus search is provided. | 86 // FocusTraversable when a focus search is provided. |
80 class SearchBoxFocusHost : public views::View { | 87 class SearchBoxFocusHost : public views::View { |
81 public: | 88 public: |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 display_observer_.Add(display::Screen::GetScreen()); | 210 display_observer_.Add(display::Screen::GetScreen()); |
204 } | 211 } |
205 | 212 |
206 AppListView::~AppListView() { | 213 AppListView::~AppListView() { |
207 delegate_->GetSpeechUI()->RemoveObserver(this); | 214 delegate_->GetSpeechUI()->RemoveObserver(this); |
208 animation_observer_.reset(); | 215 animation_observer_.reset(); |
209 // Remove child views first to ensure no remaining dependencies on delegate_. | 216 // Remove child views first to ensure no remaining dependencies on delegate_. |
210 RemoveAllChildViews(true); | 217 RemoveAllChildViews(true); |
211 } | 218 } |
212 | 219 |
213 void AppListView::Initialize(gfx::NativeView parent, int initial_apps_page) { | 220 void AppListView::Initialize(gfx::NativeView parent, |
| 221 int initial_apps_page, |
| 222 bool is_maximize_mode, |
| 223 bool is_side_shelf) { |
214 base::Time start_time = base::Time::Now(); | 224 base::Time start_time = base::Time::Now(); |
| 225 is_maximize_mode_ = is_maximize_mode; |
| 226 is_side_shelf_ = is_side_shelf; |
215 InitContents(parent, initial_apps_page); | 227 InitContents(parent, initial_apps_page); |
216 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); | 228 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); |
217 set_color(kContentsBackgroundColor); | 229 set_color(kContentsBackgroundColor); |
218 set_parent_window(parent); | 230 set_parent_window(parent); |
219 | 231 |
220 if (is_fullscreen_app_list_enabled_) | 232 if (is_fullscreen_app_list_enabled_) |
221 InitializeFullscreen(parent, initial_apps_page); | 233 InitializeFullscreen(parent, initial_apps_page); |
222 else | 234 else |
223 InitializeBubble(parent, initial_apps_page); | 235 InitializeBubble(parent, initial_apps_page); |
224 | 236 |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 | 517 |
506 void AppListView::EndDrag(const gfx::Point& location) { | 518 void AppListView::EndDrag(const gfx::Point& location) { |
507 // Change the app list state based on where the drag ended. If fling velocity | 519 // Change the app list state based on where the drag ended. If fling velocity |
508 // was over the threshold, snap to the next state in the direction of the | 520 // was over the threshold, snap to the next state in the direction of the |
509 // fling. | 521 // fling. |
510 int const new_y_position = location.y() - initial_drag_point_.y() + | 522 int const new_y_position = location.y() - initial_drag_point_.y() + |
511 fullscreen_widget_->GetWindowBoundsInScreen().y(); | 523 fullscreen_widget_->GetWindowBoundsInScreen().y(); |
512 if (std::abs(last_fling_velocity_) > kAppListDragVelocityThreshold) { | 524 if (std::abs(last_fling_velocity_) > kAppListDragVelocityThreshold) { |
513 // If the user releases drag with velocity over the threshold, snap to | 525 // If the user releases drag with velocity over the threshold, snap to |
514 // the next state, ignoring the drag release position. | 526 // the next state, ignoring the drag release position. |
515 if (app_list_state_ == FULLSCREEN) { | |
516 if (last_fling_velocity_ > 0) | |
517 SetState(PEEKING); | |
518 | 527 |
| 528 if (last_fling_velocity_ > 0) { |
| 529 switch (app_list_state_) { |
| 530 case PEEKING: |
| 531 case HALF: |
| 532 case FULLSCREEN_SEARCH: |
| 533 SetState(CLOSED); |
| 534 break; |
| 535 case FULLSCREEN_ALL_APPS: |
| 536 SetState(is_maximize_mode_ || is_side_shelf_ ? CLOSED : PEEKING); |
| 537 break; |
| 538 case CLOSED: |
| 539 NOTREACHED(); |
| 540 break; |
| 541 } |
519 } else { | 542 } else { |
520 SetState(last_fling_velocity_ > 0 ? CLOSED : FULLSCREEN); | 543 switch (app_list_state_) { |
| 544 case FULLSCREEN_ALL_APPS: |
| 545 case FULLSCREEN_SEARCH: |
| 546 SetState(app_list_state_); |
| 547 break; |
| 548 case HALF: |
| 549 SetState(FULLSCREEN_SEARCH); |
| 550 break; |
| 551 case PEEKING: |
| 552 SetState(FULLSCREEN_ALL_APPS); |
| 553 break; |
| 554 case CLOSED: |
| 555 NOTREACHED(); |
| 556 break; |
| 557 } |
521 } | 558 } |
522 last_fling_velocity_ = 0; | |
523 } else { | 559 } else { |
524 int display_height = display::Screen::GetScreen() | 560 int display_height = display::Screen::GetScreen() |
525 ->GetDisplayNearestView(parent_window()) | 561 ->GetDisplayNearestView(parent_window()) |
526 .work_area() | 562 .size() |
527 .height(); | 563 .height(); |
528 int default_peeking_y = display_height + kShelfSize - kPeekingAppListHeight; | 564 int app_list_y_for_state = 0; |
529 // The drag release velocity was too low, so use the release point. | 565 int app_list_height = 0; |
530 int app_list_snap_y = | 566 switch (app_list_state_) { |
531 (app_list_state_ == FULLSCREEN) ? 0 : default_peeking_y; | 567 case FULLSCREEN_ALL_APPS: |
532 // The DIP delta that must be exceeded for the app list to snap to the next | 568 case FULLSCREEN_SEARCH: |
533 // state. | 569 app_list_y_for_state = 0; |
534 int app_list_threshold = | 570 app_list_height = display_height; |
535 (fullscreen_widget_->GetWindowBoundsInScreen().height() + kShelfSize) / | 571 break; |
536 kAppListThresholdDenominator; | 572 case HALF: |
537 app_list_threshold -= | 573 app_list_y_for_state = display_height - kHalfAppListHeight; |
538 (app_list_state_ == FULLSCREEN ? 0 : kPeekingAppListHeight) / | 574 app_list_height = kHalfAppListHeight; |
539 kAppListThresholdDenominator; | 575 break; |
| 576 case PEEKING: |
| 577 app_list_y_for_state = display_height - kPeekingAppListHeight; |
| 578 app_list_height = kPeekingAppListHeight; |
| 579 break; |
| 580 case CLOSED: |
| 581 NOTREACHED(); |
| 582 break; |
| 583 } |
540 | 584 |
541 // If the user releases +/- 1/3 of |app_list_threshold|, snap to the | 585 int app_list_threshold = app_list_height / kAppListThresholdDenominator; |
542 // next state. | 586 int drag_delta = app_list_y_for_state - new_y_position; |
543 if (std::abs(app_list_snap_y - new_y_position) < app_list_threshold) { | 587 gfx::Point location_in_screen_coordinates = location; |
544 // The drag was not far enough so set the app list bounds to the target | 588 ConvertPointToScreen(this, &location_in_screen_coordinates); |
545 // bounds for the current state. | 589 switch (app_list_state_) { |
546 SetState(app_list_state_); | 590 case FULLSCREEN_ALL_APPS: |
547 } else if ((app_list_snap_y + app_list_threshold) < new_y_position) { | 591 if (std::abs(drag_delta) > app_list_threshold) |
548 // The drag was far enough to change states and was a downward drag, so | 592 SetState(is_maximize_mode_ || is_side_shelf_ ? CLOSED : PEEKING); |
549 // set the app list bounds to the next state. | 593 else |
550 SetState(app_list_state_ == FULLSCREEN ? PEEKING : CLOSED); | 594 SetState(app_list_state_); |
551 } else { | 595 break; |
552 // The drag was far enough to change states and was an upward drag, so | 596 case FULLSCREEN_SEARCH: |
553 // set the app list bounds to the next state. | 597 if (std::abs(drag_delta) > app_list_threshold) |
554 SetState(FULLSCREEN); | 598 SetState(CLOSED); |
| 599 else |
| 600 SetState(app_list_state_); |
| 601 break; |
| 602 case HALF: |
| 603 if (std::abs(drag_delta) > app_list_threshold) { |
| 604 SetState(drag_delta > 0 ? FULLSCREEN_SEARCH : CLOSED); |
| 605 } else if (location_in_screen_coordinates.y() >= |
| 606 display_height - kAppListBezelMargin) { |
| 607 // If the user drags to the bezel, close the app list. |
| 608 SetState(CLOSED); |
| 609 } else { |
| 610 SetState(app_list_state_); |
| 611 } |
| 612 break; |
| 613 case PEEKING: |
| 614 if (std::abs(drag_delta) > app_list_threshold) { |
| 615 SetState(drag_delta > 0 ? FULLSCREEN_ALL_APPS : CLOSED); |
| 616 } else if (location_in_screen_coordinates.y() >= |
| 617 display_height - kAppListBezelMargin) { |
| 618 // If the user drags to the bezel, close the app list. |
| 619 SetState(CLOSED); |
| 620 } else { |
| 621 SetState(app_list_state_); |
| 622 } |
| 623 break; |
| 624 case CLOSED: |
| 625 NOTREACHED(); |
| 626 break; |
555 } | 627 } |
556 } | 628 } |
557 } | 629 } |
558 | 630 |
| 631 void AppListView::SetStateFromSearchBoxView(bool search_box_is_empty) { |
| 632 switch (app_list_state_) { |
| 633 case PEEKING: |
| 634 if (!search_box_is_empty) |
| 635 SetState(HALF); |
| 636 break; |
| 637 case HALF: |
| 638 if (search_box_is_empty) |
| 639 SetState(PEEKING); |
| 640 break; |
| 641 case FULLSCREEN_SEARCH: |
| 642 if (search_box_is_empty) { |
| 643 SetState(FULLSCREEN_ALL_APPS); |
| 644 app_list_main_view()->contents_view()->SetActiveState( |
| 645 AppListModel::State::STATE_APPS); |
| 646 } |
| 647 break; |
| 648 case FULLSCREEN_ALL_APPS: |
| 649 if (!search_box_is_empty) |
| 650 SetState(FULLSCREEN_SEARCH); |
| 651 break; |
| 652 case CLOSED: |
| 653 NOTREACHED(); |
| 654 break; |
| 655 } |
| 656 } |
| 657 |
| 658 void AppListView::OnMaximizeModeChanged(bool started) { |
| 659 is_maximize_mode_ = started; |
| 660 if (is_maximize_mode_ && !is_fullscreen()) { |
| 661 // Set |app_list_state_| to a maximize mode friendly state. |
| 662 SetState(app_list_state_ == PEEKING ? FULLSCREEN_ALL_APPS |
| 663 : FULLSCREEN_SEARCH); |
| 664 } |
| 665 } |
| 666 |
559 void AppListView::OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, | 667 void AppListView::OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, |
560 views::Widget* widget) const { | 668 views::Widget* widget) const { |
561 if (!params->native_widget) { | 669 if (!params->native_widget) { |
562 views::ViewsDelegate* views_delegate = views::ViewsDelegate::GetInstance(); | 670 views::ViewsDelegate* views_delegate = views::ViewsDelegate::GetInstance(); |
563 if (views_delegate && !views_delegate->native_widget_factory().is_null()) { | 671 if (views_delegate && !views_delegate->native_widget_factory().is_null()) { |
564 params->native_widget = | 672 params->native_widget = |
565 views_delegate->native_widget_factory().Run(*params, widget); | 673 views_delegate->native_widget_factory().Run(*params, widget); |
566 } | 674 } |
567 } | 675 } |
568 // Apply a WM-provided shadow (see ui/wm/core/). | 676 // Apply a WM-provided shadow (see ui/wm/core/). |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 } | 789 } |
682 } | 790 } |
683 | 791 |
684 void AppListView::SchedulePaintInRect(const gfx::Rect& rect) { | 792 void AppListView::SchedulePaintInRect(const gfx::Rect& rect) { |
685 BubbleDialogDelegateView::SchedulePaintInRect(rect); | 793 BubbleDialogDelegateView::SchedulePaintInRect(rect); |
686 if (GetBubbleFrameView()) | 794 if (GetBubbleFrameView()) |
687 GetBubbleFrameView()->SchedulePaint(); | 795 GetBubbleFrameView()->SchedulePaint(); |
688 } | 796 } |
689 | 797 |
690 void AppListView::SetState(AppListState new_state) { | 798 void AppListView::SetState(AppListState new_state) { |
| 799 AppListState new_state_override = new_state; |
| 800 if (is_side_shelf_ || is_maximize_mode_) { |
| 801 // If side shelf or maximize mode are active, all transitions should be |
| 802 // made to the maximize mode/side shelf friendly versions. |
| 803 if (new_state == PEEKING) |
| 804 new_state_override = FULLSCREEN_ALL_APPS; |
| 805 else if (new_state == HALF) |
| 806 new_state_override = FULLSCREEN_SEARCH; |
| 807 } |
| 808 |
691 gfx::Rect new_widget_bounds = fullscreen_widget_->GetWindowBoundsInScreen(); | 809 gfx::Rect new_widget_bounds = fullscreen_widget_->GetWindowBoundsInScreen(); |
692 switch (new_state) { | 810 int display_height = display::Screen::GetScreen() |
| 811 ->GetDisplayNearestView(parent_window()) |
| 812 .work_area() |
| 813 .bottom(); |
| 814 |
| 815 switch (new_state_override) { |
693 case PEEKING: { | 816 case PEEKING: { |
694 int display_height = display::Screen::GetScreen() | 817 switch (app_list_state_) { |
695 ->GetDisplayNearestView(parent_window()) | 818 case HALF: |
696 .work_area() | 819 case FULLSCREEN_ALL_APPS: |
697 .bottom(); | 820 case PEEKING: { |
698 int default_peeking_y = | 821 int peeking_app_list_y = display_height - kPeekingAppListHeight; |
699 display_height + kShelfSize - kPeekingAppListHeight; | 822 new_widget_bounds.set_y(peeking_app_list_y); |
700 new_widget_bounds.set_y(default_peeking_y); | 823 app_list_main_view_->contents_view()->SetActiveState( |
| 824 AppListModel::STATE_START); |
| 825 break; |
| 826 } |
| 827 case FULLSCREEN_SEARCH: |
| 828 case CLOSED: |
| 829 NOTREACHED(); |
| 830 break; |
| 831 } |
701 break; | 832 break; |
702 } | 833 } |
703 case FULLSCREEN: | 834 case HALF: |
| 835 switch (app_list_state_) { |
| 836 case PEEKING: |
| 837 case HALF: { |
| 838 int half_app_list_y = display_height - kHalfAppListHeight; |
| 839 new_widget_bounds.set_y(half_app_list_y); |
| 840 break; |
| 841 } |
| 842 case FULLSCREEN_SEARCH: |
| 843 case FULLSCREEN_ALL_APPS: |
| 844 case CLOSED: |
| 845 NOTREACHED(); |
| 846 break; |
| 847 } |
| 848 break; |
| 849 case FULLSCREEN_ALL_APPS: |
| 850 new_widget_bounds.set_y(0); |
| 851 app_list_main_view_->contents_view()->SetActiveState( |
| 852 AppListModel::STATE_APPS); |
| 853 break; |
| 854 case FULLSCREEN_SEARCH: |
704 new_widget_bounds.set_y(0); | 855 new_widget_bounds.set_y(0); |
705 break; | 856 break; |
706 case CLOSED: | 857 case CLOSED: |
707 app_list_main_view_->Close(); | 858 app_list_main_view_->Close(); |
708 delegate_->Dismiss(); | 859 delegate_->Dismiss(); |
709 break; | 860 break; |
710 } | 861 } |
711 fullscreen_widget_->SetBounds(new_widget_bounds); | 862 fullscreen_widget_->SetBounds(new_widget_bounds); |
712 app_list_state_ = new_state; | 863 app_list_state_ = new_state_override; |
713 } | 864 } |
714 | 865 |
715 void AppListView::OnWidgetDestroying(views::Widget* widget) { | 866 void AppListView::OnWidgetDestroying(views::Widget* widget) { |
716 BubbleDialogDelegateView::OnWidgetDestroying(widget); | 867 BubbleDialogDelegateView::OnWidgetDestroying(widget); |
717 if (delegate_ && widget == GetWidget()) | 868 if (delegate_ && widget == GetWidget()) |
718 delegate_->ViewClosing(); | 869 delegate_->ViewClosing(); |
719 } | 870 } |
720 | 871 |
721 void AppListView::OnWidgetVisibilityChanged(views::Widget* widget, | 872 void AppListView::OnWidgetVisibilityChanged(views::Widget* widget, |
722 bool visible) { | 873 bool visible) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 .work_area() | 958 .work_area() |
808 .size(); | 959 .size(); |
809 size.Enlarge(0, kShelfSize); | 960 size.Enlarge(0, kShelfSize); |
810 fullscreen_widget_->SetSize(size); | 961 fullscreen_widget_->SetSize(size); |
811 | 962 |
812 // Update the |fullscreen_widget_| bounds to accomodate the new work area. | 963 // Update the |fullscreen_widget_| bounds to accomodate the new work area. |
813 SetState(app_list_state_); | 964 SetState(app_list_state_); |
814 } | 965 } |
815 | 966 |
816 } // namespace app_list | 967 } // namespace app_list |
OLD | NEW |