Home | History | Annotate | Download | only in gestures
      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 "ui/events/gestures/motion_event_aura.h"
      6 
      7 #include "base/logging.h"
      8 #include "ui/events/gestures/gesture_configuration.h"
      9 
     10 namespace ui {
     11 
     12 MotionEventAura::MotionEventAura()
     13     : pointer_count_(0), cached_action_index_(-1) {
     14 }
     15 
     16 MotionEventAura::MotionEventAura(
     17     size_t pointer_count,
     18     const base::TimeTicks& last_touch_time,
     19     Action cached_action,
     20     int cached_action_index,
     21     const PointData (&active_touches)[GestureSequence::kMaxGesturePoints])
     22     : pointer_count_(pointer_count),
     23       last_touch_time_(last_touch_time),
     24       cached_action_(cached_action),
     25       cached_action_index_(cached_action_index) {
     26   DCHECK(pointer_count_);
     27   for (size_t i = 0; i < pointer_count; ++i)
     28     active_touches_[i] = active_touches[i];
     29 }
     30 
     31 MotionEventAura::~MotionEventAura() {}
     32 
     33 MotionEventAura::PointData MotionEventAura::GetPointDataFromTouchEvent(
     34     const TouchEvent& touch) {
     35   PointData point_data;
     36   point_data.x = touch.x();
     37   point_data.y = touch.y();
     38   point_data.raw_x = touch.root_location_f().x();
     39   point_data.raw_y = touch.root_location_f().y();
     40   point_data.touch_id = touch.touch_id();
     41   point_data.pressure = touch.force();
     42   point_data.source_device_id = touch.source_device_id();
     43 
     44   // TODO(tdresser): at some point we should start using both radii if they are
     45   // available, but for now we use the max.
     46   point_data.major_radius = std::max(touch.radius_x(), touch.radius_y());
     47   if (!point_data.major_radius)
     48     point_data.major_radius = GestureConfiguration::default_radius();
     49   return point_data;
     50 }
     51 
     52 void MotionEventAura::OnTouch(const TouchEvent& touch) {
     53   switch (touch.type()) {
     54     case ET_TOUCH_PRESSED:
     55       AddTouch(touch);
     56       break;
     57     case ET_TOUCH_RELEASED:
     58     case ET_TOUCH_CANCELLED:
     59       // Removing these touch points needs to be postponed until after the
     60       // MotionEvent has been dispatched. This cleanup occurs in
     61       // CleanupRemovedTouchPoints.
     62       UpdateTouch(touch);
     63       break;
     64     case ET_TOUCH_MOVED:
     65       UpdateTouch(touch);
     66       break;
     67     default:
     68       NOTREACHED();
     69       break;
     70   }
     71 
     72   UpdateCachedAction(touch);
     73   last_touch_time_ = touch.time_stamp() + base::TimeTicks();
     74 }
     75 
     76 int MotionEventAura::GetId() const {
     77   return GetPointerId(0);
     78 }
     79 
     80 MotionEvent::Action MotionEventAura::GetAction() const {
     81   return cached_action_;
     82 }
     83 
     84 int MotionEventAura::GetActionIndex() const {
     85   DCHECK(cached_action_ == ACTION_POINTER_DOWN ||
     86          cached_action_ == ACTION_POINTER_UP);
     87   DCHECK_GE(cached_action_index_, 0);
     88   DCHECK_LE(cached_action_index_, static_cast<int>(pointer_count_));
     89   return cached_action_index_;
     90 }
     91 
     92 size_t MotionEventAura::GetPointerCount() const { return pointer_count_; }
     93 
     94 int MotionEventAura::GetPointerId(size_t pointer_index) const {
     95   DCHECK_LE(pointer_index, pointer_count_);
     96   return active_touches_[pointer_index].touch_id;
     97 }
     98 
     99 float MotionEventAura::GetX(size_t pointer_index) const {
    100   DCHECK_LE(pointer_index, pointer_count_);
    101   return active_touches_[pointer_index].x;
    102 }
    103 
    104 float MotionEventAura::GetY(size_t pointer_index) const {
    105   DCHECK_LE(pointer_index, pointer_count_);
    106   return active_touches_[pointer_index].y;
    107 }
    108 
    109 float MotionEventAura::GetRawX(size_t pointer_index) const {
    110   DCHECK_LE(pointer_index, pointer_count_);
    111   return active_touches_[pointer_index].raw_x;
    112 }
    113 
    114 float MotionEventAura::GetRawY(size_t pointer_index) const {
    115   DCHECK_LE(pointer_index, pointer_count_);
    116   return active_touches_[pointer_index].raw_y;
    117 }
    118 
    119 float MotionEventAura::GetTouchMajor(size_t pointer_index) const {
    120   DCHECK_LE(pointer_index, pointer_count_);
    121   return active_touches_[pointer_index].major_radius * 2;
    122 }
    123 
    124 float MotionEventAura::GetPressure(size_t pointer_index) const {
    125   DCHECK_LE(pointer_index, pointer_count_);
    126   return active_touches_[pointer_index].pressure;
    127 }
    128 
    129 base::TimeTicks MotionEventAura::GetEventTime() const {
    130   return last_touch_time_;
    131 }
    132 
    133 size_t MotionEventAura::GetHistorySize() const { return 0; }
    134 
    135 base::TimeTicks MotionEventAura::GetHistoricalEventTime(
    136     size_t historical_index) const {
    137   NOTIMPLEMENTED();
    138   return base::TimeTicks();
    139 }
    140 
    141 float MotionEventAura::GetHistoricalTouchMajor(size_t pointer_index,
    142                                              size_t historical_index) const {
    143   NOTIMPLEMENTED();
    144   return 0;
    145 }
    146 
    147 float MotionEventAura::GetHistoricalX(size_t pointer_index,
    148                                     size_t historical_index) const {
    149   NOTIMPLEMENTED();
    150   return 0;
    151 }
    152 
    153 float MotionEventAura::GetHistoricalY(size_t pointer_index,
    154                                     size_t historical_index) const {
    155   NOTIMPLEMENTED();
    156   return 0;
    157 }
    158 
    159 MotionEvent::ToolType MotionEventAura::GetToolType(size_t pointer_index) const {
    160   NOTIMPLEMENTED();
    161   return MotionEvent::TOOL_TYPE_UNKNOWN;
    162 }
    163 
    164 int MotionEventAura::GetButtonState() const {
    165   NOTIMPLEMENTED();
    166   return 0;
    167 }
    168 
    169 scoped_ptr<MotionEvent> MotionEventAura::Clone() const {
    170   return scoped_ptr<MotionEvent>(new MotionEventAura(pointer_count_,
    171                                                      last_touch_time_,
    172                                                      cached_action_,
    173                                                      cached_action_index_,
    174                                                      active_touches_));
    175 }
    176 scoped_ptr<MotionEvent> MotionEventAura::Cancel() const {
    177   return scoped_ptr<MotionEvent>(new MotionEventAura(
    178       pointer_count_, last_touch_time_, ACTION_CANCEL, -1, active_touches_));
    179 }
    180 
    181 void MotionEventAura::CleanupRemovedTouchPoints(const TouchEvent& event) {
    182   if (event.type() != ET_TOUCH_RELEASED &&
    183       event.type() != ET_TOUCH_CANCELLED) {
    184     return;
    185   }
    186 
    187   int index_to_delete = static_cast<int>(GetIndexFromId(event.touch_id()));
    188   pointer_count_--;
    189   active_touches_[index_to_delete] = active_touches_[pointer_count_];
    190 }
    191 
    192 MotionEventAura::PointData::PointData()
    193     : x(0),
    194       y(0),
    195       raw_x(0),
    196       raw_y(0),
    197       touch_id(0),
    198       pressure(0),
    199       source_device_id(0),
    200       major_radius(0) {
    201 }
    202 
    203 int MotionEventAura::GetSourceDeviceId(size_t pointer_index) const {
    204   DCHECK_LE(pointer_index, pointer_count_);
    205   return active_touches_[pointer_index].source_device_id;
    206 }
    207 
    208 void MotionEventAura::AddTouch(const TouchEvent& touch) {
    209   if (pointer_count_ == static_cast<size_t>(GestureSequence::kMaxGesturePoints))
    210     return;
    211 
    212   active_touches_[pointer_count_] = GetPointDataFromTouchEvent(touch);
    213   pointer_count_++;
    214 }
    215 
    216 
    217 void MotionEventAura::UpdateTouch(const TouchEvent& touch) {
    218   active_touches_[GetIndexFromId(touch.touch_id())] =
    219       GetPointDataFromTouchEvent(touch);
    220 }
    221 
    222 void MotionEventAura::UpdateCachedAction(const TouchEvent& touch) {
    223   DCHECK(pointer_count_);
    224   switch (touch.type()) {
    225     case ET_TOUCH_PRESSED:
    226       if (pointer_count_ == 1) {
    227         cached_action_ = ACTION_DOWN;
    228       } else {
    229         cached_action_ = ACTION_POINTER_DOWN;
    230         cached_action_index_ =
    231             static_cast<int>(GetIndexFromId(touch.touch_id()));
    232       }
    233       break;
    234     case ET_TOUCH_RELEASED:
    235       if (pointer_count_ == 1) {
    236         cached_action_ = ACTION_UP;
    237       } else {
    238         cached_action_ = ACTION_POINTER_UP;
    239         cached_action_index_ =
    240             static_cast<int>(GetIndexFromId(touch.touch_id()));
    241         DCHECK_LE(cached_action_index_, static_cast<int>(pointer_count_));
    242       }
    243       break;
    244     case ET_TOUCH_CANCELLED:
    245       cached_action_ = ACTION_CANCEL;
    246       break;
    247     case ET_TOUCH_MOVED:
    248       cached_action_ = ACTION_MOVE;
    249       break;
    250     default:
    251       NOTREACHED();
    252       break;
    253   }
    254 }
    255 
    256 size_t MotionEventAura::GetIndexFromId(int id) const {
    257   for (size_t i = 0; i < pointer_count_; ++i) {
    258     if (active_touches_[i].touch_id == id)
    259       return i;
    260   }
    261   NOTREACHED();
    262   return 0;
    263 }
    264 
    265 }  // namespace ui
    266