| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_UI_A11Y_LIB_GESTURE_MANAGER_RECOGNIZERS_SWIPE_RECOGNIZER_BASE_H_ |
| #define SRC_UI_A11Y_LIB_GESTURE_MANAGER_RECOGNIZERS_SWIPE_RECOGNIZER_BASE_H_ |
| |
| #include <lib/zx/time.h> |
| |
| #include <unordered_map> |
| |
| #include "src/ui/a11y/lib/gesture_manager/arena/contest_member.h" |
| #include "src/ui/a11y/lib/gesture_manager/arena/gesture_arena.h" |
| #include "src/ui/a11y/lib/gesture_manager/arena/recognizer.h" |
| #include "src/ui/a11y/lib/gesture_manager/gesture_util/util.h" |
| |
| namespace a11y { |
| |
| // SwipeRecognizerBase class is an abstract class that implements most of the |
| // swipe gesture recognition logic for n fingers where n >= 1. |
| // |
| // Swipe gestures are directional (up, down, right, or left), so directional recognizers |
| // will inherit from this base class and override the ValidateSwipeSlopeAndDirection() |
| // method, in which the directional differentiation logic is encapsulated. |
| class SwipeRecognizerBase : public GestureRecognizer { |
| public: |
| // Minimum distance (in NDC) between finger down and finger up events for gesture to be |
| // considered a swipe. |
| static constexpr float kMinSwipeDistance = 2.f / 8; |
| |
| // Max distance between finger down and finger up events for gesture to be considered |
| // a swipe. |
| static constexpr float kMaxSwipeDistance = 1.5; |
| |
| // Maximum duration of swipe (in milliseconds). |
| static constexpr zx::duration kDefaultSwipeGestureTimeout = zx::msec(500); |
| |
| static constexpr uint32_t kDefaultNumberOfFingers = 1; |
| |
| // Callback which will be invoked when the swipe gesture has been recognized. |
| using SwipeGestureCallback = fit::function<void(GestureContext)>; |
| |
| // Timeout is the maximum time a finger can be in contact with the screen to be considered a |
| // swipe. Callback is invoked when swipe gesture is detected and the recognizer is the winner in |
| // gesture arena. |number_of_fingers| is the number of fingers that will be used to perform the |
| // swipe gesture. |
| SwipeRecognizerBase(SwipeGestureCallback callback, uint32_t number_of_fingers, |
| zx::duration swipe_gesture_timeout, const std::string& debug_name); |
| ~SwipeRecognizerBase() override; |
| |
| void HandleEvent(const fuchsia::ui::input::accessibility::PointerEvent& pointer_event) override; |
| void OnWin() override; |
| void OnDefeat() override; |
| void OnContestStarted(std::unique_ptr<ContestMember> contest_member) override; |
| std::string DebugName() const override = 0; |
| |
| protected: |
| // Swipe gestures are directional (up, down, right, or left). In order to be recognized as a |
| // swipe, the slope of the line containing the gesture start and end points must fall within a |
| // specified range, which varies based on the direction of the swipe. Furthermore, the slopes of |
| // the lines containing each pointer event location and the gesture start point must also fall |
| // within this range. If a swipe recognizer receives a pointer event for which this slope property |
| // does NOT hold, the recognizer will abandon the gesture. Each directional recognizer must |
| // specify the range of acceptable slopes by implementing the method below, which verifies that a |
| // given slope value falls within that range. |
| virtual bool SwipeHasValidSlopeAndDirection(float x_displacement, float y_displacement) const = 0; |
| |
| private: |
| // Represents state internal to a contest, i.e. contest member, hold timeout, and tap state. |
| struct Contest; |
| |
| // Determines whether a gesture's is close enough to up, down, left, or right to be |
| // remain in consideration as a swipe. Returns true if so, false otherwise. |
| bool ValidateSwipePath( |
| uint32_t pointer_id, |
| const fuchsia::ui::input::accessibility::PointerEvent& pointer_event) const; |
| |
| // Checks if the distance between the start and end points of a swipe fall within the accepted |
| // range. |
| bool ValidateSwipeDistance( |
| uint32_t pointer_id, |
| const fuchsia::ui::input::accessibility::PointerEvent& pointer_event) const; |
| |
| // Checks if the distance between the start and end points of a swipe is more than |
| // kMinSwipeDistance. |
| bool MinSwipeLengthAchieved( |
| uint32_t pointer_id, |
| const fuchsia::ui::input::accessibility::PointerEvent& pointer_event) const; |
| |
| // Helper function to save GestureInfo for last pointer position. |
| void UpdateLastPointerPosition( |
| uint32_t pointer_id, const fuchsia::ui::input::accessibility::PointerEvent& pointer_event); |
| |
| // Stores the Gesture Context which is required to execute the callback. |
| GestureContext gesture_context_; |
| |
| // Callback which will be executed when the gesture is performed. |
| SwipeGestureCallback swipe_gesture_callback_; |
| |
| // Swipe gesture timeout(in milliseconds). If the gesture is not completed within this time |
| // period, then it won't be recognized. |
| const zx::duration swipe_gesture_timeout_; |
| |
| // Stores GestureInfo per pointer id(pointer id represents a unique finger). |
| // GestureInfo is used to store the initial state of the gesture per finger. |
| std::unordered_map<uint32_t, GestureInfo> gesture_info_map_; |
| |
| // Stores point after which finger should start stopping. This is needed when one of the finger is |
| // removed then all the other fingers should then start coming to a stop. |
| std::unordered_map<uint32_t, GestureInfo> stopping_position_; |
| |
| // Tracks how many times the up event is detected. |
| uint32_t number_of_up_event_detected_ = 0; |
| |
| // Number of fingers that will be used to perform the swipe gesture. |
| uint32_t number_of_fingers_ = kDefaultNumberOfFingers; |
| |
| // String name of the recognizer, to be used in logs only. |
| const std::string debug_name_; |
| |
| std::unique_ptr<Contest> contest_; |
| }; |
| |
| } // namespace a11y |
| |
| #endif // SRC_UI_A11Y_LIB_GESTURE_MANAGER_RECOGNIZERS_SWIPE_RECOGNIZER_BASE_H_ |