Chromium Code Reviews| Index: ui/app_list/views/app_list_view.cc |
| diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc |
| index a38c6092e4bd9be4872f4008e16246d1c1d9cb77..6796eb2d759c7891ba09d1c7bc96e4563bfdbdfc 100644 |
| --- a/ui/app_list/views/app_list_view.cc |
| +++ b/ui/app_list/views/app_list_view.cc |
| @@ -61,6 +61,9 @@ constexpr int kShelfSize = 48; |
| // The height of the peeking app list. |
| constexpr int kPeekingAppListHeight = 320; |
| +// The height of the half app list. |
| +constexpr int kHalfAppListHeight = 561; |
| + |
| // The fraction of app list height that the app list must be released at in |
| // order to transition to the next state. |
| constexpr int kAppListThresholdDenominator = 3; |
| @@ -69,18 +72,16 @@ constexpr int kAppListThresholdDenominator = 3; |
| // state, measured in DIPs/event. |
| constexpr int kAppListDragVelocityThreshold = 25; |
| +// The DIP distance from the bezel that a drag event must end within to transfer |
| +// the |app_list_state_|. |
| +constexpr int kAppListBezelMargin = 50; |
| + |
| // The opacity of the app list background. |
| constexpr float kAppListOpacity = 0.8; |
| // The vertical position for the appearing animation of the speech UI. |
| constexpr float kSpeechUIAppearingPosition = 12; |
| -bool IsFullscreenAppListEnabled() { |
| - // Cache this value to avoid repeated lookup. |
| - static bool cached_value = features::IsFullscreenAppListEnabled(); |
| - return cached_value; |
| -} |
| - |
| // This view forwards the focus to the search box widget by providing it as a |
| // FocusTraversable when a focus search is provided. |
| class SearchBoxFocusHost : public views::View { |
| @@ -197,6 +198,7 @@ AppListView::AppListView(AppListViewDelegate* delegate) |
| search_box_focus_host_(nullptr), |
| search_box_widget_(nullptr), |
| search_box_view_(nullptr), |
| + is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()), |
| app_list_state_(PEEKING), |
| display_observer_(this), |
| overlay_view_(nullptr), |
| @@ -205,7 +207,7 @@ AppListView::AppListView(AppListViewDelegate* delegate) |
| delegate_->GetSpeechUI()->AddObserver(this); |
| - if (IsFullscreenAppListEnabled()) |
| + if (is_fullscreen_app_list_enabled_) |
| display_observer_.Add(display::Screen::GetScreen()); |
| } |
| @@ -216,14 +218,19 @@ AppListView::~AppListView() { |
| RemoveAllChildViews(true); |
| } |
| -void AppListView::Initialize(gfx::NativeView parent, int initial_apps_page) { |
| +void AppListView::Initialize(gfx::NativeView parent, |
| + int initial_apps_page, |
| + bool is_maximize_mode, |
| + bool is_side_shelf) { |
| base::Time start_time = base::Time::Now(); |
| + is_maximize_mode_ = is_maximize_mode; |
| + is_side_shelf_ = is_side_shelf; |
| InitContents(parent, initial_apps_page); |
| AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); |
| set_color(kContentsBackgroundColor); |
| set_parent_window(parent); |
| - if (IsFullscreenAppListEnabled()) |
| + if (is_fullscreen_app_list_enabled_) |
| InitializeFullscreen(parent, initial_apps_page); |
| else |
| InitializeBubble(parent, initial_apps_page); |
| @@ -231,7 +238,7 @@ void AppListView::Initialize(gfx::NativeView parent, int initial_apps_page) { |
| InitChildWidgets(); |
| AddChildView(overlay_view_); |
| - if (IsFullscreenAppListEnabled()) |
| + if (is_fullscreen_app_list_enabled_) |
| SetState(app_list_state_); |
| if (delegate_) |
| @@ -249,7 +256,7 @@ void AppListView::SetBubbleArrow(views::BubbleBorder::Arrow arrow) { |
| void AppListView::MaybeSetAnchorPoint(const gfx::Point& anchor_point) { |
| // if the AppListView is a bubble |
| - if (!IsFullscreenAppListEnabled()) |
| + if (!is_fullscreen_app_list_enabled_) |
| SetAnchorRect(gfx::Rect(anchor_point, gfx::Size())); |
| } |
| @@ -264,7 +271,7 @@ void AppListView::ShowWhenReady() { |
| void AppListView::UpdateBounds() { |
| // if the AppListView is a bubble |
| - if (!IsFullscreenAppListEnabled()) |
| + if (!is_fullscreen_app_list_enabled_) |
| SizeToContents(); |
| } |
| @@ -357,7 +364,7 @@ void AppListView::InitContents(gfx::NativeView parent, int initial_apps_page) { |
| FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| "440224, 441028 AppListView::InitContents")); |
| - if (IsFullscreenAppListEnabled()) { |
| + if (is_fullscreen_app_list_enabled_) { |
| // The shield view that colors the background of the app list and makes it |
| // transparent. |
| app_list_background_shield_ = new views::View; |
| @@ -518,50 +525,146 @@ void AppListView::EndDrag(const gfx::Point& location) { |
| if (std::abs(last_fling_velocity_) > kAppListDragVelocityThreshold) { |
| // If the user releases drag with velocity over the threshold, snap to |
| // the next state, ignoring the drag release position. |
| - if (app_list_state_ == FULLSCREEN) { |
| - if (last_fling_velocity_ > 0) |
| - SetState(PEEKING); |
| + if (last_fling_velocity_ > 0) { |
| + switch (app_list_state_) { |
| + case PEEKING: |
| + case HALF: |
| + case FULLSCREEN_SEARCH: |
| + SetState(CLOSED); |
| + break; |
| + case FULLSCREEN_ALL_APPS: |
| + SetState(is_maximize_mode_ || is_side_shelf_ ? CLOSED : PEEKING); |
| + break; |
| + case CLOSED: |
| + NOTREACHED(); |
| + break; |
| + } |
| } else { |
| - SetState(last_fling_velocity_ > 0 ? CLOSED : FULLSCREEN); |
| + switch (app_list_state_) { |
| + case FULLSCREEN_ALL_APPS: |
| + case FULLSCREEN_SEARCH: |
| + SetState(app_list_state_); |
| + break; |
| + case HALF: |
| + SetState(FULLSCREEN_SEARCH); |
| + break; |
| + case PEEKING: |
| + SetState(FULLSCREEN_ALL_APPS); |
| + break; |
| + case CLOSED: |
| + NOTREACHED(); |
| + break; |
| + } |
| } |
| - last_fling_velocity_ = 0; |
| } else { |
| int display_height = display::Screen::GetScreen() |
| ->GetDisplayNearestView(parent_window()) |
| .work_area() |
| .height(); |
| - int default_peeking_y = display_height + kShelfSize - kPeekingAppListHeight; |
| - // The drag release velocity was too low, so use the release point. |
| - int app_list_snap_y = |
| - (app_list_state_ == FULLSCREEN) ? 0 : default_peeking_y; |
| - // The DIP delta that must be exceeded for the app list to snap to the next |
| - // state. |
| - int app_list_threshold = |
| - (fullscreen_widget_->GetWindowBoundsInScreen().height() + kShelfSize) / |
| - kAppListThresholdDenominator; |
| - app_list_threshold -= |
| - (app_list_state_ == FULLSCREEN ? 0 : kPeekingAppListHeight) / |
| - kAppListThresholdDenominator; |
| - |
| - // If the user releases +/- 1/3 of |app_list_threshold|, snap to the |
| - // next state. |
| - if (std::abs(app_list_snap_y - new_y_position) < app_list_threshold) { |
| - // The drag was not far enough so set the app list bounds to the target |
| - // bounds for the current state. |
| - SetState(app_list_state_); |
| - } else if ((app_list_snap_y + app_list_threshold) < new_y_position) { |
| - // The drag was far enough to change states and was a downward drag, so |
| - // set the app list bounds to the next state. |
| - SetState(app_list_state_ == FULLSCREEN ? PEEKING : CLOSED); |
| - } else { |
| - // The drag was far enough to change states and was an upward drag, so |
| - // set the app list bounds to the next state. |
| - SetState(FULLSCREEN); |
| + int app_list_y_for_state = 0; |
| + int app_list_height = 0; |
| + switch (app_list_state_) { |
| + case FULLSCREEN_ALL_APPS: |
| + case FULLSCREEN_SEARCH: |
| + app_list_y_for_state = 0; |
| + app_list_height = display_height; |
| + break; |
| + case HALF: |
| + app_list_y_for_state = display_height - kHalfAppListHeight; |
| + app_list_height = kHalfAppListHeight; |
| + break; |
| + case PEEKING: |
| + app_list_y_for_state = display_height - kPeekingAppListHeight; |
| + app_list_height = kPeekingAppListHeight; |
| + break; |
| + case CLOSED: |
| + NOTREACHED(); |
| + break; |
| + } |
| + |
| + int app_list_threshold = app_list_height / kAppListThresholdDenominator; |
| + int drag_delta = app_list_y_for_state - new_y_position; |
| + switch (app_list_state_) { |
| + case FULLSCREEN_ALL_APPS: |
| + if (std::abs(drag_delta) > app_list_threshold) |
| + SetState(is_maximize_mode_ || is_side_shelf_ ? CLOSED : PEEKING); |
| + else |
| + SetState(app_list_state_); |
| + break; |
| + case FULLSCREEN_SEARCH: |
| + if (std::abs(drag_delta) > app_list_threshold) |
| + SetState(CLOSED); |
| + else |
| + SetState(app_list_state_); |
| + break; |
| + case HALF: |
| + if (std::abs(drag_delta) > app_list_threshold) { |
| + SetState(drag_delta > 0 ? FULLSCREEN_SEARCH : CLOSED); |
| + } else if (location.y() + |
| + fullscreen_widget_->GetWindowBoundsInScreen().y() >= |
| + display_height - kAppListBezelMargin) { |
| + // If the user drags to the bezel, close the app list. |
| + SetState(CLOSED); |
| + } else { |
| + SetState(app_list_state_); |
| + } |
| + break; |
| + case PEEKING: |
| + if (std::abs(drag_delta) > app_list_threshold) { |
| + SetState(drag_delta > 0 ? FULLSCREEN_ALL_APPS : CLOSED); |
| + } else if (location.y() + |
| + fullscreen_widget_->GetWindowBoundsInScreen().y() >= |
| + display_height - kAppListBezelMargin) { |
| + // If the user drags to the bezel, close the app list. |
| + SetState(CLOSED); |
| + } else { |
| + SetState(app_list_state_); |
| + } |
| + break; |
| + case CLOSED: |
| + NOTREACHED(); |
| + break; |
| } |
| } |
| } |
| +void AppListView::SetStateFromSearchBoxView(bool search_box_is_empty) { |
| + switch (app_list_state_) { |
| + case PEEKING: |
| + if (!search_box_is_empty) |
| + SetState(HALF); |
| + break; |
| + case HALF: |
| + if (search_box_is_empty) |
| + SetState(PEEKING); |
| + break; |
| + case FULLSCREEN_SEARCH: |
| + if (search_box_is_empty) { |
| + SetState(FULLSCREEN_ALL_APPS); |
| + app_list_main_view()->contents_view()->SetActiveState( |
| + AppListModel::State::STATE_APPS); |
| + } |
| + break; |
| + case FULLSCREEN_ALL_APPS: |
| + if (!search_box_is_empty) |
| + SetState(FULLSCREEN_SEARCH); |
| + break; |
| + case CLOSED: |
| + NOTREACHED(); |
| + break; |
| + } |
| +} |
| + |
| +void AppListView::OnMaximizeModeChanged(bool started) { |
| + is_maximize_mode_ = started; |
| + if (is_maximize_mode_ && !is_fullscreen()) { |
| + // Set |app_list_state_| to a maximize mode friendly state. |
| + SetState(app_list_state_ == PEEKING ? FULLSCREEN_ALL_APPS |
| + : FULLSCREEN_SEARCH); |
| + } |
| +} |
| + |
| void AppListView::OnBeforeBubbleWidgetInit(views::Widget::InitParams* params, |
| views::Widget* widget) const { |
| if (!params->native_widget) { |
| @@ -596,7 +699,7 @@ void AppListView::GetWidgetHitTestMask(gfx::Path* mask) const { |
| } |
| void AppListView::OnMouseEvent(ui::MouseEvent* event) { |
| - if (!IsFullscreenAppListEnabled()) |
| + if (!is_fullscreen_app_list_enabled_) |
| return; |
| switch (event->type()) { |
| @@ -618,7 +721,7 @@ void AppListView::OnMouseEvent(ui::MouseEvent* event) { |
| } |
| void AppListView::OnGestureEvent(ui::GestureEvent* event) { |
| - if (!IsFullscreenAppListEnabled()) |
| + if (!is_fullscreen_app_list_enabled_) |
| return; |
| switch (event->type()) { |
| @@ -646,7 +749,7 @@ bool AppListView::AcceleratorPressed(const ui::Accelerator& accelerator) { |
| // If the ContentsView does not handle the back action, then this is the |
| // top level, so we close the app list. |
| if (!app_list_main_view_->contents_view()->Back()) { |
| - if (IsFullscreenAppListEnabled()) { |
| + if (is_fullscreen_app_list_enabled_) { |
| SetState(CLOSED); |
| } else { |
| app_list_main_view_->Close(); |
| @@ -681,7 +784,7 @@ void AppListView::Layout() { |
| speech_view_->SetBoundsRect(speech_bounds); |
| } |
| - if (IsFullscreenAppListEnabled()) { |
| + if (is_fullscreen_app_list_enabled_) { |
| app_list_main_view_->contents_view()->Layout(); |
| app_list_background_shield_->SetBoundsRect(contents_bounds); |
| } |
| @@ -694,19 +797,61 @@ void AppListView::SchedulePaintInRect(const gfx::Rect& rect) { |
| } |
| void AppListView::SetState(AppListState new_state) { |
| + AppListState new_state_override = new_state; |
| + if (is_side_shelf_ || is_maximize_mode_) { |
| + // If side shelf or maximize mode are active, all transitions should be |
| + // made to the maximize mode/side shelf friendly versions. |
| + if (new_state == PEEKING) |
| + new_state_override = FULLSCREEN_ALL_APPS; |
| + else if (new_state == HALF) |
| + new_state_override = FULLSCREEN_SEARCH; |
| + } |
| + |
| gfx::Rect new_widget_bounds = fullscreen_widget_->GetWindowBoundsInScreen(); |
| - switch (new_state) { |
| + int display_height = display::Screen::GetScreen() |
| + ->GetDisplayNearestView(parent_window()) |
| + .work_area() |
| + .bottom(); |
| + |
| + switch (new_state_override) { |
| case PEEKING: { |
| - int display_height = display::Screen::GetScreen() |
| - ->GetDisplayNearestView(parent_window()) |
| - .work_area() |
| - .bottom(); |
| - int default_peeking_y = |
| - display_height + kShelfSize - kPeekingAppListHeight; |
| - new_widget_bounds.set_y(default_peeking_y); |
| + switch (app_list_state_) { |
| + case HALF: |
| + case FULLSCREEN_ALL_APPS: |
| + case PEEKING: { |
| + int peeking_app_list_y = display_height - kPeekingAppListHeight; |
| + new_widget_bounds.set_y(peeking_app_list_y); |
| + app_list_main_view_->contents_view()->SetActiveState( |
| + AppListModel::STATE_START); |
| + break; |
| + } |
| + case FULLSCREEN_SEARCH: |
| + case CLOSED: |
| + NOTREACHED(); |
| + break; |
| + } |
| + } break; |
|
xiyuan
2017/06/14 17:02:58
This style is wrong. Prevailing style is
either p
newcomer
2017/06/15 16:55:33
git cl format kept resetting the break to the inco
|
| + case HALF: |
| + switch (app_list_state_) { |
| + case PEEKING: |
| + case HALF: { |
| + int half_app_list_y = display_height - kHalfAppListHeight; |
| + new_widget_bounds.set_y(half_app_list_y); |
| + break; |
| + } |
| + case FULLSCREEN_SEARCH: |
| + case FULLSCREEN_ALL_APPS: |
| + case CLOSED: |
| + NOTREACHED(); |
| + break; |
| + } |
| break; |
| - } |
| - case FULLSCREEN: |
| + case FULLSCREEN_ALL_APPS: |
| + new_widget_bounds.set_y(0); |
| + app_list_main_view_->contents_view()->SetActiveState( |
| + AppListModel::STATE_APPS); |
| + break; |
| + case FULLSCREEN_SEARCH: |
| new_widget_bounds.set_y(0); |
| break; |
| case CLOSED: |
| @@ -715,7 +860,7 @@ void AppListView::SetState(AppListState new_state) { |
| break; |
| } |
| fullscreen_widget_->SetBounds(new_widget_bounds); |
| - app_list_state_ = new_state; |
| + app_list_state_ = new_state_override; |
| } |
| void AppListView::OnWidgetDestroying(views::Widget* widget) { |
| @@ -804,7 +949,7 @@ void AppListView::OnSpeechRecognitionStateChanged( |
| void AppListView::OnDisplayMetricsChanged(const display::Display& display, |
| uint32_t changed_metrics) { |
| - if (!IsFullscreenAppListEnabled()) |
| + if (!is_fullscreen_app_list_enabled_) |
| return; |
| // Set the |fullscreen_widget_| size to fit the new display metrics. |