ec687d305145b86d918d2ce92f5cb844aa38fb01
[platform/core/uifw/dali-core.git] / dali / public-api / events / pan-gesture-detector.h
1 #ifndef DALI_PAN_GESTURE_DETECTOR_H
2 #define DALI_PAN_GESTURE_DETECTOR_H
3
4 /*
5  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <cstdint> // uint32_t
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/events/gesture-detector.h>
26 #include <dali/public-api/events/pan-gesture.h>
27 #include <dali/public-api/object/property-index-ranges.h>
28 #include <dali/public-api/signals/dali-signal.h>
29
30 namespace Dali
31 {
32
33 struct Radian;
34
35 namespace Internal DALI_INTERNAL
36 {
37 class PanGestureDetector;
38 }
39
40 /**
41  * @addtogroup dali_core_events
42  * @{
43  */
44
45 /**
46  * @brief This class looks for panning (or dragging) gestures.
47  *
48  * The user will be pressing one or more fingers on an actor while they pan it.
49  *
50  * The application programmer can use this gesture detector as follows:
51  * @code
52  * PanGestureDetector detector = PanGestureDetector::New();
53  * detector.Attach(myActor);
54  * detector.DetectedSignal().Connect(this, &MyApplication::OnPan);
55  *
56  * // Detect pan gesture for single and double touch.
57  * detector.SetMaximumTouchesRequired(2);
58  * @endcode
59  *
60  * @SINCE_1_0.0
61  * @see PanGesture
62  *
63  * Signals
64  * | %Signal Name | Method                |
65  * |--------------|-----------------------|
66  * | panDetected  | @ref DetectedSignal() |
67  */
68 class DALI_CORE_API PanGestureDetector : public GestureDetector
69 {
70 public:
71
72   /**
73    * @brief Enumeration for the instance of properties belonging to the PanGestureDetector class.
74    * @SINCE_1_0.0
75    */
76   struct Property
77   {
78     /**
79      * @brief Enumeration for the instance of properties belonging to the PanGestureDetector class.
80      * @SINCE_1_0.0
81      */
82     enum
83     {
84       SCREEN_POSITION = DEFAULT_GESTURE_DETECTOR_PROPERTY_START_INDEX, ///< name "screenPosition",      type Vector2 @SINCE_1_0.0
85       SCREEN_DISPLACEMENT,                                             ///< name "screenDisplacement",  type Vector2 @SINCE_1_0.0
86       SCREEN_VELOCITY,                                                 ///< name "screenVelocity",      type Vector2 @SINCE_1_0.0
87       LOCAL_POSITION,                                                  ///< name "localPosition",       type Vector2 @SINCE_1_0.0
88       LOCAL_DISPLACEMENT,                                              ///< name "localDisplacement",   type Vector2 @SINCE_1_0.0
89       LOCAL_VELOCITY,                                                  ///< name "localVelocity",       type Vector2 @SINCE_1_0.0
90       PANNING,                                                         ///< name "panning",             type bool @SINCE_1_0.0
91     };
92   };
93
94   // Typedefs
95   typedef Signal< void ( Actor, const PanGesture& ) > DetectedSignalType; ///< Pan gesture detected signal type @SINCE_1_0.0
96
97   // Directional Pan
98   typedef std::pair< Radian, Radian > AngleThresholdPair; ///< Range of angles for a direction @SINCE_1_0.0
99
100   static const Radian DIRECTION_LEFT;       ///< For a left pan (-PI Radians).
101   static const Radian DIRECTION_RIGHT;      ///< For a right pan (0 Radians).
102   static const Radian DIRECTION_UP;         ///< For an up pan (-0.5 * PI Radians).
103   static const Radian DIRECTION_DOWN;       ///< For a down pan (0.5 * PI Radians).
104   static const Radian DIRECTION_HORIZONTAL; ///< For a left and right pan (PI Radians). Useful for AddDirection().
105   static const Radian DIRECTION_VERTICAL;   ///< For an up and down pan (-0.5 * PI Radians). Useful for AddDirection().
106
107   static const Radian DEFAULT_THRESHOLD;    ///< The default threshold is PI * 0.25 radians (or 45 degrees).
108
109 public: // Creation & Destruction
110
111   /**
112    * @brief Creates an uninitialized PanGestureDetector; this can be initialized with PanGestureDetector::New().
113    *
114    * Calling member functions with an uninitialized PanGestureDetector handle is not allowed.
115    * @SINCE_1_0.0
116    */
117   PanGestureDetector();
118
119   /**
120    * @brief Creates an initialized PanGestureDetector.
121    *
122    * @SINCE_1_0.0
123    * @return A handle to a newly allocated Dali resource
124    */
125   static PanGestureDetector New();
126
127   /**
128    * @brief Downcasts a handle to PanGestureDetector handle.
129    *
130    * If handle points to a PanGestureDetector object, the
131    * downcast produces valid handle. If not, the returned handle is left uninitialized.
132    * @SINCE_1_0.0
133    * @param[in] handle Handle to an object
134    * @return Handle to a PanGestureDetector object or an uninitialized handle
135    */
136   static PanGestureDetector DownCast( BaseHandle handle );
137
138   /**
139    * @brief Destructor.
140    *
141    * This is non-virtual since derived Handle types must not contain data or virtual methods.
142    * @SINCE_1_0.0
143    */
144   ~PanGestureDetector();
145
146   /**
147    * @brief This copy constructor is required for (smart) pointer semantics.
148    *
149    * @SINCE_1_0.0
150    * @param[in] handle A reference to the copied handle
151    */
152   PanGestureDetector(const PanGestureDetector& handle);
153
154   /**
155    * @brief This assignment operator is required for (smart) pointer semantics.
156    *
157    * @SINCE_1_0.0
158    * @param[in] rhs A reference to the copied handle
159    * @return A reference to this
160    */
161   PanGestureDetector& operator=(const PanGestureDetector& rhs);
162
163 public: // Setters
164
165   /**
166    * @brief This is the minimum number of touches required for the pan gesture to be detected.
167    *
168    * @SINCE_1_0.0
169    * @param[in] minimum Minimum touches required
170    * @pre The gesture detector has been initialized.
171    * @note The default minimum is '1'.
172    */
173   void SetMinimumTouchesRequired(uint32_t minimum);
174
175   /**
176    * @brief This is the maximum number of touches required for the pan gesture to be detected.
177    *
178    * @SINCE_1_0.0
179    * @param[in] maximum Maximum touches required
180    * @pre The gesture detector has been initialized.
181    * @note The default maximum is '1'.
182    */
183   void SetMaximumTouchesRequired(uint32_t maximum);
184
185 public: // Getters
186
187   /**
188    * @brief Retrieves the minimum number of touches required for the pan gesture to be detected.
189    *
190    * @SINCE_1_0.0
191    * @return The minimum touches required
192    * @pre The gesture detector has been initialized.
193    */
194   uint32_t GetMinimumTouchesRequired() const;
195
196   /**
197    * @brief Retrieves the maximum number of touches required for the pan gesture to be detected.
198    *
199    * @SINCE_1_0.0
200    * @return The maximum touches required
201    * @pre The gesture detector has been initialized.
202    */
203   uint32_t GetMaximumTouchesRequired() const;
204
205 public: // Directional Panning
206
207   /**
208    * @brief The pan gesture is only emitted if the pan occurs in the direction specified by this method with a +/- threshold allowance.
209    *
210    * The angle is from -180 -> 0 -> 180 degrees (or -M_PI -> 0 -> M_PI in radians) i.e:
211    *
212    * @code
213    *           -90.0f ( -0.5f * PI )
214    *                     |
215    *                     |
216    * 180.0f ( PI ) ------------- 0.0f ( 0.0f )
217    *                     |
218    *                     |
219    *            90.0f ( 0.5f * PI )
220    * @endcode
221    *
222    * If an angle of 0.0 degrees is specified and the threshold is 45 degrees then the acceptable
223    * direction range is from -45 to 45 degrees.
224    *
225    * @SINCE_1_0.0
226    * @param[in] angle     The angle that pan should be allowed
227    * @param[in] threshold The threshold around that angle
228    *
229    * @pre The gesture detector has been initialized.
230    * @note The angle added using this API is only checked when the gesture first starts, after that,
231    *       this detector will emit the gesture regardless of what angle the pan is moving.
232    * @note The user can add as many angles as they require.
233    * @note If an angle outside the range above is given, then it is wrapped within the range, i.e.
234    *       190 degrees becomes -170 degrees and 370 degrees becomes 10 degrees.
235    * @note As long as you specify the type, you can also pass in a Dali::Degree to this method.
236    * @note If no threshold is provided, then the default threshold (PI * 0.25) is used.
237    * @note If the threshold is greater than PI, then PI will be used as the threshold.
238    *
239    */
240   void AddAngle( Radian angle, Radian threshold = DEFAULT_THRESHOLD );
241
242   /**
243    * @brief A helper method for adding bi-directional angles where the pan should take place.
244    *
245    * In other words, if 0 is requested, then PI will also be added so that we have both left and
246    * right scrolling.
247    *
248    * @SINCE_1_0.0
249    * @param[in] direction The direction of panning required
250    * @param[in] threshold The threshold
251    *
252    * @pre The gesture detector has been initialized.
253    *
254    * @note If a direction outside the range above is given, then it is wrapped within the range, i.e.
255    *       190 degrees becomes -170 degrees and 370 degrees becomes 10 degrees.
256    * @note If no threshold is provided, then the default threshold (PI * 0.25) is used.
257    * @note If the threshold is greater than PI, then PI will be used as the threshold.
258    * @note As long as you specify the type, you can also pass in a Dali::Degree to this method.
259    *
260    * @see AddAngle
261    */
262   void AddDirection( Radian direction, Radian threshold = DEFAULT_THRESHOLD );
263
264   /**
265    * @brief Returns the count of angles that this pan gesture detector emits a signal.
266    *
267    * @SINCE_1_0.0
268    * @return The count
269    * @pre The gesture detector has been initialized.
270    */
271   size_t GetAngleCount() const;
272
273   /**
274    * @brief Returns the angle by index that this pan gesture detector emits a signal.
275    *
276    * @SINCE_1_0.0
277    * @param[in] index The angle's index
278    * @return An angle threshold pair, or a zero valued angle pair when index is invalid
279    * @pre The gesture detector has been initialized.
280    * @pre The index is less than GetAngleCount()
281    */
282   AngleThresholdPair GetAngle(size_t index) const;
283
284   /**
285    * @brief Clears any directional angles that are used by the gesture detector.
286    *
287    * After this, the pan gesture
288    * will be emitted for a pan in ANY direction.
289    * @SINCE_1_0.0
290    * @pre The gesture detector has been initialized.
291    */
292   void ClearAngles();
293
294   /**
295    * @brief Removes the angle specified from the container.
296    *
297    * @SINCE_1_0.0
298    * @param[in] angle The angle to remove
299    * @pre The gesture detector has been initialized.
300    * @note This will only remove the first instance of the angle found from the container.
301    * @note If an angle outside the range in AddAngle() is given, then the value is wrapped within
302    *       the range and that is removed.
303    */
304   void RemoveAngle( Radian angle );
305
306   /**
307    * @brief Removes the two angles that make up the direction from the container.
308    *
309    * @SINCE_1_0.0
310    * @param[in] direction The direction to remove
311    * @pre The gesture detector has been initialized.
312    * @note If a direction outside the range in AddAngle() is given, then the value is wrapped within
313    *       the range and that is removed.
314    */
315   void RemoveDirection( Radian direction );
316
317 public: // Signals
318
319   /**
320    * @brief This signal is emitted when the pan gesture is detected on the attached actor.
321    *
322    * A callback of the following type may be connected:
323    * @code
324    *   void YourCallbackName( Actor actor, const PanGesture& gesture );
325    * @endcode
326    * @SINCE_1_0.0
327    * @return The signal to connect to
328    * @pre The gesture detector has been initialized.
329    */
330   DetectedSignalType& DetectedSignal();
331
332 public: // Pan Properties Setters
333
334   /**
335    * @brief Allows setting of the pan properties that are returned in constraints.
336    *
337    * @SINCE_1_0.0
338    * @param[in] pan The pan gesture to set
339    * @note If a normal pan is taking place, then any value set is ignored.
340    */
341   static void SetPanGestureProperties( const PanGesture& pan );
342
343 public: // Not intended for Application developers
344
345   /// @cond internal
346   /**
347    * @brief This constructor is used by PanGestureDetector::New() methods.
348    *
349    * @SINCE_1_0.0
350    * @param[in] internal A pointer to a newly allocated Dali resource
351    */
352   explicit DALI_INTERNAL PanGestureDetector(Internal::PanGestureDetector* internal);
353   /// @endcond
354
355 };
356
357 /**
358  * @}
359  */
360
361 } // namespace Dali
362
363 #endif // DALI_PAN_GESTURE_DETECTOR_H