| 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 88afaf450b0199148ad3e2fda373ff59abfbc6cf..128b018f2dcde90c6ba3207842482f48d98945ee 100644
|
| --- a/ui/app_list/views/app_list_view.cc
|
| +++ b/ui/app_list/views/app_list_view.cc
|
| @@ -55,12 +55,15 @@ namespace {
|
| // The margin from the edge to the speech UI.
|
| constexpr int kSpeechUIMargin = 12;
|
|
|
| -// The height/width of the shelf.
|
| +// The height/width of the shelf from the bottom/side of the screen.
|
| constexpr int kShelfSize = 48;
|
|
|
| -// The height of the peeking app list.
|
| +// The height of the peeking app list from the bottom of the screen.
|
| constexpr int kPeekingAppListHeight = 320;
|
|
|
| +// The height of the half app list from the bottom of the screen.
|
| +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,6 +72,10 @@ 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;
|
|
|
| @@ -210,8 +217,13 @@ 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);
|
| @@ -512,50 +524,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()
|
| + .size()
|
| .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;
|
| + gfx::Point location_in_screen_coordinates = location;
|
| + ConvertPointToScreen(this, &location_in_screen_coordinates);
|
| + 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_in_screen_coordinates.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_in_screen_coordinates.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) {
|
| @@ -688,19 +796,62 @@ 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;
|
| }
|
| - case FULLSCREEN:
|
| + 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_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:
|
| @@ -709,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) {
|
|
|