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