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/gesture_detection/velocity_tracker_state.h"
6 
7 #include "base/check_op.h"
8 #include "ui/events/gesture_detection/motion_event.h"
9 
10 namespace ui {
11 namespace {
12 // Special constant to request the velocity of the active pointer.
13 const int ACTIVE_POINTER_ID = -1;
14 }
15 
VelocityTrackerState(VelocityTracker::Strategy strategy)16 VelocityTrackerState::VelocityTrackerState(VelocityTracker::Strategy strategy)
17     : velocity_tracker_(strategy), active_pointer_id_(ACTIVE_POINTER_ID) {}
18 
~VelocityTrackerState()19 VelocityTrackerState::~VelocityTrackerState() {}
20 
Clear()21 void VelocityTrackerState::Clear() {
22   velocity_tracker_.Clear();
23   active_pointer_id_ = ACTIVE_POINTER_ID;
24   calculated_id_bits_.clear();
25 }
26 
AddMovement(const MotionEvent & event)27 void VelocityTrackerState::AddMovement(const MotionEvent& event) {
28   velocity_tracker_.AddMovement(event);
29 }
30 
ComputeCurrentVelocity(int32_t units,float max_velocity)31 void VelocityTrackerState::ComputeCurrentVelocity(int32_t units,
32                                                   float max_velocity) {
33   DCHECK_GE(max_velocity, 0);
34 
35   BitSet32 id_bits(velocity_tracker_.GetCurrentPointerIdBits());
36   calculated_id_bits_ = id_bits;
37 
38   for (uint32_t index = 0; !id_bits.is_empty(); index++) {
39     uint32_t id = id_bits.clear_first_marked_bit();
40 
41     float vx, vy;
42     velocity_tracker_.GetVelocity(id, &vx, &vy);
43 
44     vx = vx * units / 1000.f;
45     vy = vy * units / 1000.f;
46 
47     if (vx > max_velocity)
48       vx = max_velocity;
49     else if (vx < -max_velocity)
50       vx = -max_velocity;
51 
52     if (vy > max_velocity)
53       vy = max_velocity;
54     else if (vy < -max_velocity)
55       vy = -max_velocity;
56 
57     Velocity& velocity = calculated_velocity_[index];
58     velocity.vx = vx;
59     velocity.vy = vy;
60   }
61 }
62 
GetXVelocity(int32_t id) const63 float VelocityTrackerState::GetXVelocity(int32_t id) const {
64   float vx;
65   GetVelocity(id, &vx, NULL);
66   return vx;
67 }
68 
GetYVelocity(int32_t id) const69 float VelocityTrackerState::GetYVelocity(int32_t id) const {
70   float vy;
71   GetVelocity(id, NULL, &vy);
72   return vy;
73 }
74 
GetVelocity(int32_t id,float * out_vx,float * out_vy) const75 void VelocityTrackerState::GetVelocity(int32_t id,
76                                        float* out_vx,
77                                        float* out_vy) const {
78   DCHECK(out_vx || out_vy);
79   if (id == ACTIVE_POINTER_ID)
80     id = velocity_tracker_.GetActivePointerId();
81 
82   float vx, vy;
83   if (id >= 0 && id <= MotionEvent::MAX_POINTER_ID &&
84       calculated_id_bits_.has_bit(id)) {
85     uint32_t index = calculated_id_bits_.get_index_of_bit(id);
86     const Velocity& velocity = calculated_velocity_[index];
87     vx = velocity.vx;
88     vy = velocity.vy;
89   } else {
90     vx = 0;
91     vy = 0;
92   }
93 
94   if (out_vx)
95     *out_vx = vx;
96 
97   if (out_vy)
98     *out_vy = vy;
99 }
100 
101 }  // namespace ui
102