mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Make the gesture detector treat all touches fully individually. Fixes issues with last commit.
This commit is contained in:
parent
a8d6de26e3
commit
19bf222ea4
@ -9,14 +9,7 @@
|
||||
|
||||
const float estimatedInertiaDamping = 0.75f;
|
||||
|
||||
GestureDetector::GestureDetector()
|
||||
: active_(0),
|
||||
estimatedInertiaX_(0.0f),
|
||||
estimatedInertiaY_(0.0f) {
|
||||
memset(pointers, 0, sizeof(pointers));
|
||||
}
|
||||
|
||||
TouchInput GestureDetector::Update(const TouchInput &touch, int scrollTouchId, const Bounds &bounds) {
|
||||
TouchInput GestureDetector::Update(const TouchInput &touch, const Bounds &bounds) {
|
||||
// Mouse / 1-finger-touch control.
|
||||
Pointer &p = pointers[touch.id];
|
||||
if ((touch.flags & TOUCH_DOWN) && bounds.Contains(touch.x, touch.y)) {
|
||||
@ -28,50 +21,50 @@ TouchInput GestureDetector::Update(const TouchInput &touch, int scrollTouchId, c
|
||||
p.lastY = touch.y;
|
||||
p.distanceX = 0.0f;
|
||||
p.distanceY = 0.0f;
|
||||
estimatedInertiaX_ = 0.0f;
|
||||
estimatedInertiaY_ = 0.0f;
|
||||
p.estimatedInertiaX = 0.0f;
|
||||
p.estimatedInertiaY = 0.0f;
|
||||
} else if (touch.flags & TOUCH_UP) {
|
||||
p.down = false;
|
||||
} else {
|
||||
p.distanceX += fabsf(touch.x - p.lastX);
|
||||
p.distanceY += fabsf(touch.y - p.lastY);
|
||||
|
||||
estimatedInertiaX_ += touch.x - p.lastX;
|
||||
estimatedInertiaY_ += touch.y - p.lastY;
|
||||
estimatedInertiaX_ *= estimatedInertiaDamping;
|
||||
estimatedInertiaY_ *= estimatedInertiaDamping;
|
||||
p.estimatedInertiaX += touch.x - p.lastX;
|
||||
p.estimatedInertiaY += touch.y - p.lastY;
|
||||
p.estimatedInertiaX *= estimatedInertiaDamping;
|
||||
p.estimatedInertiaY *= estimatedInertiaDamping;
|
||||
|
||||
p.lastX = touch.x;
|
||||
p.lastY = touch.y;
|
||||
}
|
||||
|
||||
if (touch.id == scrollTouchId && p.distanceY > p.distanceX) {
|
||||
if (p.distanceY > p.distanceX) {
|
||||
if (p.down) {
|
||||
double timeDown = time_now_d() - p.downTime;
|
||||
if (!active_ && p.distanceY * timeDown > 3) {
|
||||
active_ |= GESTURE_DRAG_VERTICAL;
|
||||
if (!p.active && p.distanceY * timeDown > 3) {
|
||||
p.active |= GESTURE_DRAG_VERTICAL;
|
||||
// Kill the drag
|
||||
TouchInput inp2 = touch;
|
||||
inp2.flags = TOUCH_UP | TOUCH_CANCEL;
|
||||
return inp2;
|
||||
}
|
||||
} else {
|
||||
active_ = 0;
|
||||
p.active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (touch.id == scrollTouchId && p.distanceX > p.distanceY) {
|
||||
if (p.distanceX > p.distanceY) {
|
||||
if (p.down) {
|
||||
double timeDown = time_now_d() - p.downTime;
|
||||
if (!active_ && p.distanceX * timeDown > 3) {
|
||||
active_ |= GESTURE_DRAG_HORIZONTAL;
|
||||
if (!p.active && p.distanceX * timeDown > 3) {
|
||||
p.active |= GESTURE_DRAG_HORIZONTAL;
|
||||
// Kill the drag
|
||||
TouchInput inp2 = touch;
|
||||
inp2.flags = TOUCH_UP | TOUCH_CANCEL;
|
||||
return inp2;
|
||||
}
|
||||
} else {
|
||||
active_ = 0;
|
||||
p.active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,28 +72,34 @@ TouchInput GestureDetector::Update(const TouchInput &touch, int scrollTouchId, c
|
||||
}
|
||||
|
||||
void GestureDetector::UpdateFrame() {
|
||||
estimatedInertiaX_ *= estimatedInertiaDamping;
|
||||
estimatedInertiaY_ *= estimatedInertiaDamping;
|
||||
for (int i = 0; i < MAX_PTRS; i++) {
|
||||
pointers[i].estimatedInertiaX *= estimatedInertiaDamping;
|
||||
pointers[i].estimatedInertiaY *= estimatedInertiaDamping;
|
||||
}
|
||||
}
|
||||
|
||||
bool GestureDetector::IsGestureActive(Gesture gesture) const {
|
||||
return (active_ & gesture) != 0;
|
||||
bool GestureDetector::IsGestureActive(Gesture gesture, int touchId) const {
|
||||
if (touchId < 0)
|
||||
return false;
|
||||
return (pointers[touchId].active & gesture) != 0;
|
||||
}
|
||||
|
||||
bool GestureDetector::GetGestureInfo(Gesture gesture, int touchId, float info[4]) const {
|
||||
if (touchId < 0)
|
||||
return false;
|
||||
memset(info, 0, sizeof(float) * 4);
|
||||
if (!(active_ & gesture)) {
|
||||
if (!(pointers[touchId].active & gesture)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (gesture) {
|
||||
case GESTURE_DRAG_HORIZONTAL:
|
||||
info[0] = pointers[touchId].lastX - pointers[touchId].downX;
|
||||
info[1] = estimatedInertiaX_;
|
||||
info[1] = pointers[touchId].estimatedInertiaX;
|
||||
return true;
|
||||
case GESTURE_DRAG_VERTICAL:
|
||||
info[0] = pointers[touchId].lastY - pointers[touchId].downY;
|
||||
info[1] = estimatedInertiaY_;
|
||||
info[1] = pointers[touchId].estimatedInertiaY;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -16,14 +16,12 @@ enum Gesture {
|
||||
// with the gesture you are interested in.
|
||||
class GestureDetector {
|
||||
public:
|
||||
GestureDetector();
|
||||
TouchInput Update(const TouchInput &touch, int scrollTouchId, const Bounds &bounds);
|
||||
TouchInput Update(const TouchInput &touch, const Bounds &bounds);
|
||||
void UpdateFrame();
|
||||
bool IsGestureActive(Gesture gesture) const;
|
||||
bool IsGestureActive(Gesture gesture, int touchId) const;
|
||||
bool GetGestureInfo(Gesture gesture, int touchId, float info[4]) const;
|
||||
|
||||
private:
|
||||
// jazzhands!
|
||||
enum Locals {
|
||||
MAX_PTRS = 10,
|
||||
};
|
||||
@ -39,13 +37,11 @@ private:
|
||||
float deltaY;
|
||||
float distanceX;
|
||||
float distanceY;
|
||||
float estimatedInertiaX;
|
||||
float estimatedInertiaY;
|
||||
|
||||
uint32_t active;
|
||||
};
|
||||
|
||||
Pointer pointers[MAX_PTRS];
|
||||
|
||||
uint32_t active_;
|
||||
|
||||
// For inertia estimation
|
||||
float estimatedInertiaX_;
|
||||
float estimatedInertiaY_;
|
||||
Pointer pointers[MAX_PTRS]{};
|
||||
};
|
||||
|
@ -752,7 +752,7 @@ void ScrollView::Touch(const TouchInput &input) {
|
||||
|
||||
TouchInput input2;
|
||||
if (CanScroll()) {
|
||||
input2 = gesture_.Update(input, scrollTouchId_, bounds_);
|
||||
input2 = gesture_.Update(input, bounds_);
|
||||
float info[4];
|
||||
if (input.id == scrollTouchId_ && gesture_.GetGestureInfo(gesture, input.id, info) && !(input.flags & TOUCH_DOWN)) {
|
||||
float pos = scrollStart_ - info[0];
|
||||
@ -890,7 +890,7 @@ float ScrollView::ClampedScrollPos(float pos) {
|
||||
|
||||
Gesture gesture = orientation_ == ORIENT_VERTICAL ? GESTURE_DRAG_VERTICAL : GESTURE_DRAG_HORIZONTAL;
|
||||
|
||||
if (gesture_.IsGestureActive(gesture)) {
|
||||
if (scrollTouchId_ != -1 && gesture_.IsGestureActive(gesture, scrollTouchId_)) {
|
||||
float maxPull = bounds_.h * 0.1f;
|
||||
if (pos < 0.0f) {
|
||||
float dist = std::min(-pos * (1.0f / bounds_.h), 1.0f);
|
||||
@ -951,14 +951,14 @@ void ScrollView::Update() {
|
||||
} else {
|
||||
scrollPos_ += (target - scrollPos_) * 0.3f;
|
||||
}
|
||||
} else if (inertia_ != 0.0f && !gesture_.IsGestureActive(gesture)) {
|
||||
} else if (inertia_ != 0.0f && !gesture_.IsGestureActive(gesture, scrollTouchId_)) {
|
||||
scrollPos_ -= inertia_;
|
||||
inertia_ *= friction;
|
||||
if (fabsf(inertia_) < stop_threshold)
|
||||
inertia_ = 0.0f;
|
||||
}
|
||||
|
||||
if (!gesture_.IsGestureActive(gesture)) {
|
||||
if (!gesture_.IsGestureActive(gesture, scrollTouchId_)) {
|
||||
scrollPos_ = ClampedScrollPos(scrollPos_);
|
||||
|
||||
pull_ *= friction;
|
||||
|
Loading…
Reference in New Issue
Block a user