Home | History | Annotate | Download | only in home
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "athena/home/home_card_gesture_manager.h"
      6 
      7 #include "athena/home/home_card_constants.h"
      8 #include "ui/events/event.h"
      9 
     10 namespace athena {
     11 
     12 namespace {
     13 
     14 // The maximum height, in pixels, of a home card with final state
     15 // VISIBLE_MINIMIZED.
     16 const int kMinimizedFinalStateMaxHeight = 50 + kHomeCardMinimizedHeight;
     17 
     18 // The maximum height, in pixels, of an initially centered home card with final
     19 // state VISIBLE_MINIMIZED.
     20 const int kMinimizedFinalStateMaxHeightInitiallyCentered =
     21     90 + kHomeCardMinimizedHeight;
     22 
     23 // The minimum height, as a percentage of the screen height, of a home card with
     24 // final state VISIBLE_CENTERED.
     25 const float kCenteredFinalStateMinScreenRatio = 0.5f;
     26 
     27 // The minimum height, as a percentage of the screen height, of an initially
     28 // minimized home card with final state VISIBLE_CENTERED.
     29 const float kCenteredFinalStateMinScreenRatioInitiallyMinimized = 0.3f;
     30 
     31 }
     32 
     33 HomeCardGestureManager::HomeCardGestureManager(Delegate* delegate,
     34                                                const gfx::Rect& screen_bounds)
     35     : delegate_(delegate),
     36       original_state_(HomeCard::HIDDEN),
     37       y_offset_(0),
     38       last_estimated_height_(0),
     39       screen_bounds_(screen_bounds) {}
     40 
     41 HomeCardGestureManager::~HomeCardGestureManager() {}
     42 
     43 void HomeCardGestureManager::ProcessGestureEvent(ui::GestureEvent* event) {
     44   switch (event->type()) {
     45     case ui::ET_GESTURE_SCROLL_BEGIN:
     46       y_offset_ = event->location().y();
     47       original_state_ = HomeCard::Get()->GetState();
     48       DCHECK_NE(HomeCard::HIDDEN, original_state_);
     49       event->SetHandled();
     50       break;
     51     case ui::ET_GESTURE_SCROLL_END:
     52       event->SetHandled();
     53       delegate_->OnGestureEnded(GetFinalState(), false);
     54       break;
     55     case ui::ET_GESTURE_SCROLL_UPDATE:
     56       UpdateScrollState(*event);
     57       break;
     58     case ui::ET_SCROLL_FLING_START: {
     59       const ui::GestureEventDetails& details = event->details();
     60       const float kFlingCompletionVelocity = 100.0f;
     61       HomeCard::State final_state = GetFinalState();
     62 
     63       // When the user does not drag far enough to switch the final state, but
     64       // a fling happens at the end of the gesture, the state should change
     65       // based on the direction of the fling.
     66       // Checking |final_state| == |original_state| may cause unexpected results
     67       // for gestures where the user flings in the opposite direction that they
     68       // moved the home card (e.g. drag home card up from minimized state and
     69       // then fling down)
     70       // TODO(mukai): Consider this case once reported.
     71       bool is_fling = ::fabs(details.velocity_y()) > kFlingCompletionVelocity;
     72       if (final_state == original_state_ && is_fling) {
     73         if (details.velocity_y() > 0) {
     74           final_state = std::min(HomeCard::VISIBLE_MINIMIZED,
     75                                  static_cast<HomeCard::State>(final_state + 1));
     76         } else {
     77           final_state = std::max(HomeCard::VISIBLE_CENTERED,
     78                                  static_cast<HomeCard::State>(final_state - 1));
     79         }
     80       }
     81       delegate_->OnGestureEnded(final_state, is_fling);
     82       break;
     83     }
     84     default:
     85       // do nothing.
     86       break;
     87   }
     88 }
     89 
     90 HomeCard::State HomeCardGestureManager::GetFinalState() const {
     91   int max_height = (original_state_ == HomeCard::VISIBLE_CENTERED)
     92       ? kMinimizedFinalStateMaxHeightInitiallyCentered
     93       : kMinimizedFinalStateMaxHeight;
     94   if (last_estimated_height_ < max_height)
     95     return HomeCard::VISIBLE_MINIMIZED;
     96 
     97   float ratio = (original_state_ == HomeCard::VISIBLE_MINIMIZED)
     98       ? kCenteredFinalStateMinScreenRatioInitiallyMinimized
     99       : kCenteredFinalStateMinScreenRatio;
    100   if (last_estimated_height_ < screen_bounds_.height() * ratio)
    101     return HomeCard::VISIBLE_BOTTOM;
    102 
    103   return HomeCard::VISIBLE_CENTERED;
    104 }
    105 
    106 void HomeCardGestureManager::UpdateScrollState(const ui::GestureEvent& event) {
    107   last_estimated_height_ =
    108       screen_bounds_.height() - event.root_location().y() + y_offset_;
    109 
    110   if (last_estimated_height_ <= kHomeCardMinimizedHeight) {
    111     delegate_->OnGestureProgressed(
    112         HomeCard::VISIBLE_BOTTOM, HomeCard::VISIBLE_MINIMIZED, 1.0f);
    113     return;
    114   }
    115 
    116   HomeCard::State bigger_state = HomeCard::VISIBLE_BOTTOM;
    117   float smaller_height = kHomeCardMinimizedHeight;
    118   float bigger_height = kHomeCardHeight;
    119   if (last_estimated_height_ > kHomeCardHeight) {
    120     bigger_state = HomeCard::VISIBLE_CENTERED;
    121     smaller_height = kHomeCardHeight;
    122     bigger_height = screen_bounds_.height();
    123   }
    124 
    125   // The finger is between two states.
    126   float progress = (last_estimated_height_ - smaller_height) /
    127       (bigger_height - smaller_height);
    128   progress = std::min(1.0f, std::max(0.0f, progress));
    129 
    130   delegate_->OnGestureProgressed(
    131       static_cast<HomeCard::State>(bigger_state + 1),
    132       bigger_state,
    133       progress);
    134 }
    135 
    136 }  // namespace athena
    137