1 /*
2   ==============================================================================
3 
4    This file is part of the JUCE library.
5    Copyright (c) 2020 - Raw Material Software Limited
6 
7    JUCE is an open source library subject to commercial or open-source
8    licensing.
9 
10    By using JUCE, you agree to the terms of both the JUCE 6 End-User License
11    Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
12 
13    End User License Agreement: www.juce.com/juce-6-licence
14    Privacy Policy: www.juce.com/juce-privacy-policy
15 
16    Or: You may also use this code under the terms of the GPL v3 (see
17    www.gnu.org/licenses).
18 
19    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21    DISCLAIMED.
22 
23   ==============================================================================
24 */
25 
26 namespace juce
27 {
28 
29 //==============================================================================
30 /**
31     Contains position and status information about a mouse event.
32 
33     @see MouseListener, Component::mouseMove, Component::mouseEnter, Component::mouseExit,
34          Component::mouseDown, Component::mouseUp, Component::mouseDrag
35 
36     @tags{GUI}
37 */
38 class JUCE_API  MouseEvent  final
39 {
40 public:
41     //==============================================================================
42     /** Creates a MouseEvent.
43 
44         Normally an application will never need to use this.
45 
46         @param source           the source that's invoking the event
47         @param position         the position of the mouse, relative to the component that is passed-in
48         @param modifiers        the key modifiers at the time of the event
49         @param pressure         the pressure of the touch or stylus, in the range 0 to 1. Devices that
50                                 do not support force information may return 0.0, 1.0, or a negative value,
51                                 depending on the platform
52         @param orientation      the orientation of the touch input for this event in radians. The default is 0
53         @param rotation         the rotation of the pen device for this event in radians. The default is 0
54         @param tiltX            the tilt of the pen device along the x-axis between -1.0 and 1.0. The default is 0
55         @param tiltY            the tilt of the pen device along the y-axis between -1.0 and 1.0. The default is 0
56         @param eventComponent   the component that the mouse event applies to
57         @param originator       the component that originally received the event
58         @param eventTime        the time the event happened
59         @param mouseDownPos     the position of the corresponding mouse-down event (relative to the component that is passed-in).
60                                 If there isn't a corresponding mouse-down (e.g. for a mouse-move), this will just be
61                                 the same as the current mouse-x position.
62         @param mouseDownTime    the time at which the corresponding mouse-down event happened
63                                 If there isn't a corresponding mouse-down (e.g. for a mouse-move), this will just be
64                                 the same as the current mouse-event time.
65         @param numberOfClicks   how many clicks, e.g. a double-click event will be 2, a triple-click will be 3, etc
66         @param mouseWasDragged  whether the mouse has been dragged significantly since the previous mouse-down
67     */
68     MouseEvent (MouseInputSource source,
69                 Point<float> position,
70                 ModifierKeys modifiers,
71                 float pressure,
72                 float orientation, float rotation,
73                 float tiltX, float tiltY,
74                 Component* eventComponent,
75                 Component* originator,
76                 Time eventTime,
77                 Point<float> mouseDownPos,
78                 Time mouseDownTime,
79                 int numberOfClicks,
80                 bool mouseWasDragged) noexcept;
81 
82     /** Destructor. */
83     ~MouseEvent() noexcept;
84 
85     //==============================================================================
86     /** The position of the mouse when the event occurred.
87 
88         This value is relative to the top-left of the component to which the
89         event applies (as indicated by the MouseEvent::eventComponent field).
90 
91         This is a more accurate floating-point version of the position returned by
92         getPosition() and the integer x and y member variables.
93     */
94     const Point<float> position;
95 
96     /** The x-position of the mouse when the event occurred.
97 
98         This value is relative to the top-left of the component to which the
99         event applies (as indicated by the MouseEvent::eventComponent field).
100 
101         For a floating-point coordinate, see MouseEvent::position
102     */
103     const int x;
104 
105     /** The y-position of the mouse when the event occurred.
106 
107         This value is relative to the top-left of the component to which the
108         event applies (as indicated by the MouseEvent::eventComponent field).
109 
110         For a floating-point coordinate, see MouseEvent::position
111     */
112     const int y;
113 
114     /** The key modifiers associated with the event.
115 
116         This will let you find out which mouse buttons were down, as well as which
117         modifier keys were held down.
118 
119         When used for mouse-up events, this will indicate the state of the mouse buttons
120         just before they were released, so that you can tell which button they let go of.
121     */
122     const ModifierKeys mods;
123 
124     /** The pressure of the touch or stylus for this event.
125         The range is 0 (soft) to 1 (hard).
126         If the input device doesn't provide any pressure data, it may return a negative
127         value here, or 0.0 or 1.0, depending on the platform.
128     */
129     const float pressure;
130 
131     /** The orientation of the touch input for this event in radians where 0 indicates a touch aligned with the x-axis
132         and pointing from left to right; increasing values indicate rotation in the clockwise direction. The default is 0.
133     */
134     const float orientation;
135 
136     /** The rotation of the pen device for this event in radians. Indicates the clockwise
137         rotation, or twist, of the pen. The default is 0.
138     */
139     const float rotation;
140 
141     /** The tilt of the pen device along the x-axis between -1.0 and 1.0. A positive value indicates
142         a tilt to the right. The default is 0.
143     */
144     const float tiltX;
145 
146     /** The tilt of the pen device along the y-axis between -1.0 and 1.0. A positive value indicates
147         a tilt toward the user. The default is 0.
148     */
149     const float tiltY;
150 
151     /** The coordinates of the last place that a mouse button was pressed.
152         The coordinates are relative to the component specified in MouseEvent::component.
153         @see getDistanceFromDragStart, getDistanceFromDragStartX, mouseWasDraggedSinceMouseDown
154     */
155     const Point<float> mouseDownPosition;
156 
157     /** The component that this event applies to.
158 
159         This is usually the component that the mouse was over at the time, but for mouse-drag
160         events the mouse could actually be over a different component and the events are
161         still sent to the component that the button was originally pressed on.
162 
163         The x and y member variables are relative to this component's position.
164 
165         If you use getEventRelativeTo() to retarget this object to be relative to a different
166         component, this pointer will be updated, but originalComponent remains unchanged.
167 
168         @see originalComponent
169     */
170     Component* const eventComponent;
171 
172     /** The component that the event first occurred on.
173 
174         If you use getEventRelativeTo() to retarget this object to be relative to a different
175         component, this value remains unchanged to indicate the first component that received it.
176 
177         @see eventComponent
178     */
179     Component* const originalComponent;
180 
181     /** The time that this mouse-event occurred. */
182     const Time eventTime;
183 
184     /** The time that the corresponding mouse-down event occurred. */
185     const Time mouseDownTime;
186 
187     /** The source device that generated this event. */
188     MouseInputSource source;
189 
190     //==============================================================================
191     /** Returns the x coordinate of the last place that a mouse was pressed.
192         The coordinate is relative to the component specified in MouseEvent::component.
193         @see getDistanceFromDragStart, getDistanceFromDragStartX, mouseWasDraggedSinceMouseDown
194     */
195     int getMouseDownX() const noexcept;
196 
197     /** Returns the y coordinate of the last place that a mouse was pressed.
198         The coordinate is relative to the component specified in MouseEvent::component.
199         @see getDistanceFromDragStart, getDistanceFromDragStartX, mouseWasDraggedSinceMouseDown
200     */
201     int getMouseDownY() const noexcept;
202 
203     /** Returns the coordinates of the last place that a mouse was pressed.
204         The coordinates are relative to the component specified in MouseEvent::component.
205         For a floating point version of this value, see mouseDownPosition.
206         @see mouseDownPosition, getDistanceFromDragStart, getDistanceFromDragStartX, mouseWasDraggedSinceMouseDown
207     */
208     Point<int> getMouseDownPosition() const noexcept;
209 
210     /** Returns the straight-line distance between where the mouse is now and where it
211         was the last time the button was pressed.
212 
213         This is quite handy for things like deciding whether the user has moved far enough
214         for it to be considered a drag operation.
215 
216         @see getDistanceFromDragStartX
217     */
218     int getDistanceFromDragStart() const noexcept;
219 
220     /** Returns the difference between the mouse's current x position and where it was
221         when the button was last pressed.
222 
223         @see getDistanceFromDragStart
224     */
225     int getDistanceFromDragStartX() const noexcept;
226 
227     /** Returns the difference between the mouse's current y position and where it was
228         when the button was last pressed.
229 
230         @see getDistanceFromDragStart
231     */
232     int getDistanceFromDragStartY() const noexcept;
233 
234     /** Returns the difference between the mouse's current position and where it was
235         when the button was last pressed.
236 
237         @see getDistanceFromDragStart
238     */
239     Point<int> getOffsetFromDragStart() const noexcept;
240 
241     /** Returns true if the user seems to be performing a drag gesture.
242 
243         This is only meaningful if called in either a mouseUp() or mouseDrag() method.
244 
245         It will return true if the user has dragged the mouse more than a few pixels from the place
246         where the mouse-down occurred or the mouse has been held down for a significant amount of time.
247 
248         Once they have dragged it far enough for this method to return true, it will continue
249         to return true until the mouse-up, even if they move the mouse back to the same
250         location at which the mouse-down happened. This means that it's very handy for
251         objects that can either be clicked on or dragged, as you can use it in the mouseDrag()
252         callback to ignore small movements they might make while trying to click.
253     */
254     bool mouseWasDraggedSinceMouseDown() const noexcept;
255 
256     /** Returns true if the mouse event is part of a click gesture rather than a drag.
257         This is effectively the opposite of mouseWasDraggedSinceMouseDown()
258     */
259     bool mouseWasClicked() const noexcept;
260 
261     /** For a click event, the number of times the mouse was clicked in succession.
262         So for example a double-click event will return 2, a triple-click 3, etc.
263     */
getNumberOfClicks()264     int getNumberOfClicks() const noexcept                              { return numberOfClicks; }
265 
266     /** Returns the time that the mouse button has been held down for.
267 
268         If called from a mouseDrag or mouseUp callback, this will return the
269         number of milliseconds since the corresponding mouseDown event occurred.
270         If called in other contexts, e.g. a mouseMove, then the returned value
271         may be 0 or an undefined value.
272     */
273     int getLengthOfMousePress() const noexcept;
274 
275     /** Returns true if the pressure value for this event is meaningful. */
276     bool isPressureValid() const noexcept;
277 
278     /** Returns true if the orientation value for this event is meaningful. */
279     bool isOrientationValid() const noexcept;
280 
281     /** Returns true if the rotation value for this event is meaningful. */
282     bool isRotationValid() const noexcept;
283 
284     /** Returns true if the current tilt value (either x- or y-axis) is meaningful. */
285     bool isTiltValid (bool tiltX) const noexcept;
286 
287     //==============================================================================
288     /** The position of the mouse when the event occurred.
289 
290         This position is relative to the top-left of the component to which the
291         event applies (as indicated by the MouseEvent::eventComponent field).
292 
293         For a floating-point position, see MouseEvent::position
294     */
295     Point<int> getPosition() const noexcept;
296 
297     /** Returns the mouse x position of this event, in global screen coordinates.
298         The coordinates are relative to the top-left of the main monitor.
299         @see getScreenPosition
300     */
301     int getScreenX() const;
302 
303     /** Returns the mouse y position of this event, in global screen coordinates.
304         The coordinates are relative to the top-left of the main monitor.
305         @see getScreenPosition
306     */
307     int getScreenY() const;
308 
309     /** Returns the mouse position of this event, in global screen coordinates.
310         The coordinates are relative to the top-left of the main monitor.
311         @see getMouseDownScreenPosition
312     */
313     Point<int> getScreenPosition() const;
314 
315     /** Returns the x coordinate at which the mouse button was last pressed.
316         The coordinates are relative to the top-left of the main monitor.
317         @see getMouseDownScreenPosition
318     */
319     int getMouseDownScreenX() const;
320 
321     /** Returns the y coordinate at which the mouse button was last pressed.
322         The coordinates are relative to the top-left of the main monitor.
323         @see getMouseDownScreenPosition
324     */
325     int getMouseDownScreenY() const;
326 
327     /** Returns the coordinates at which the mouse button was last pressed.
328         The coordinates are relative to the top-left of the main monitor.
329         @see getScreenPosition
330     */
331     Point<int> getMouseDownScreenPosition() const;
332 
333     //==============================================================================
334     /** Creates a version of this event that is relative to a different component.
335 
336         The x and y positions of the event that is returned will have been
337         adjusted to be relative to the new component.
338         The component pointer that is passed-in must not be null.
339     */
340     MouseEvent getEventRelativeTo (Component* newComponent) const noexcept;
341 
342     /** Creates a copy of this event with a different position.
343         All other members of the event object are the same, but the x and y are
344         replaced with these new values.
345     */
346     MouseEvent withNewPosition (Point<float> newPosition) const noexcept;
347 
348     /** Creates a copy of this event with a different position.
349         All other members of the event object are the same, but the x and y are
350         replaced with these new values.
351     */
352     MouseEvent withNewPosition (Point<int> newPosition) const noexcept;
353 
354     //==============================================================================
355     /** Changes the application-wide setting for the double-click time limit.
356 
357         This is the maximum length of time between mouse-clicks for it to be
358         considered a double-click. It's used by the Component class.
359 
360         @see getDoubleClickTimeout, MouseListener::mouseDoubleClick
361     */
362     static void setDoubleClickTimeout (int timeOutMilliseconds) noexcept;
363 
364     /** Returns the application-wide setting for the double-click time limit.
365 
366         This is the maximum length of time between mouse-clicks for it to be
367         considered a double-click. It's used by the Component class.
368 
369         @see setDoubleClickTimeout, MouseListener::mouseDoubleClick
370     */
371     static int getDoubleClickTimeout() noexcept;
372 
373 
374 private:
375     //==============================================================================
376     const uint8 numberOfClicks, wasMovedSinceMouseDown;
377 
378     MouseEvent& operator= (const MouseEvent&);
379 };
380 
381 
382 //==============================================================================
383 /**
384     Contains status information about a mouse wheel event.
385 
386     @see MouseListener, MouseEvent
387 
388     @tags{GUI}
389 */
390 struct MouseWheelDetails  final
391 {
392     //==============================================================================
393     /** The amount that the wheel has been moved in the X axis.
394 
395         If isReversed is true, then a negative deltaX means that the wheel has been
396         pushed physically to the left.
397         If isReversed is false, then a negative deltaX means that the wheel has been
398         pushed physically to the right.
399     */
400     float deltaX;
401 
402     /** The amount that the wheel has been moved in the Y axis.
403 
404         If isReversed is true, then a negative deltaY means that the wheel has been
405         pushed physically upwards.
406         If isReversed is false, then a negative deltaY means that the wheel has been
407         pushed physically downwards.
408     */
409     float deltaY;
410 
411     /** Indicates whether the user has reversed the direction of the wheel.
412         See deltaX and deltaY for an explanation of the effects of this value.
413     */
414     bool isReversed;
415 
416     /** If true, then the wheel has continuous, un-stepped motion. */
417     bool isSmooth;
418 
419     /** If true, then this event is part of the inertial momentum phase that follows
420         the wheel being released. */
421     bool isInertial;
422 };
423 
424 //==============================================================================
425 /**
426     Contains status information about a pen event.
427 
428     @see MouseListener, MouseEvent
429 
430     @tags{GUI}
431 */
432 struct PenDetails  final
433 {
434     /**
435         The rotation of the pen device in radians. Indicates the clockwise rotation, or twist,
436         of the pen. The default is 0.
437     */
438     float rotation;
439 
440     /**
441         Indicates the angle of tilt of the pointer in a range of -1.0 to 1.0 along the x-axis where
442         a positive value indicates a tilt to the right. The default is 0.
443     */
444     float tiltX;
445 
446     /**
447         Indicates the angle of tilt of the pointer in a range of -1.0 to 1.0 along the y-axis where
448         a positive value indicates a tilt toward the user. The default is 0.
449     */
450     float tiltY;
451 };
452 
453 } // namespace juce
454