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