1 // This may look like C code, but it's really -*- C++ -*-
2 /*
3  * Copyright (C) 2008 Emweb bv, Herent, Belgium.
4  *
5  * See the LICENSE file for terms of use.
6  */
7 #ifndef WEVENT_H_
8 #define WEVENT_H_
9 
10 #include <Wt/WGlobal.h>
11 #include <string>
12 #include <vector>
13 
14 namespace Wt {
15 
16   /*! \brief A coordinate.
17    */
18   struct Coordinates {
19     int x; //!< X coordinate
20     int y; //!< Y coordinate
21 
22     operator WPointF() const;
23 
24     /*! \brief Constructor.
25      */
CoordinatesCoordinates26     Coordinates(int X, int Y) : x(X), y(Y) { }
27   };
28 
29   /*! \brief A single finger touch of a touch event.
30    *
31    * \sa WTouchEvent
32    */
33   class WT_API Touch {
34   public:
35     /*! \brief Constructor.
36      */
37     Touch(long long identifier,
38 	  int clientX, int clientY,
39 	  int documentX, int documentY,
40 	  int screenX, int screenY,
41 	  int widgetX, int widgetY);
42 
43     /*! \brief Returns the touch position relative to the document.
44      */
document()45     Coordinates document() const { return Coordinates(documentX_, documentY_); }
46 
47     /*! \brief Returns the touch position relative to the window.
48      *
49      * This differs from document() only when scrolling through
50      * the document.
51      */
window()52     Coordinates window() const { return Coordinates(clientX_, clientY_); }
53 
54     /*! \brief Returns the touch position relative to the screen.
55      */
screen()56     Coordinates screen() const { return Coordinates(screenX_, screenY_); }
57 
58     /*! \brief Returns the touch position relative to the widget.
59      */
widget()60     Coordinates widget() const { return Coordinates(widgetX_, widgetY_); }
61 
62     /*! \brief Returns the identifier for this touch.
63      */
identifier()64     long long identifier() const { return identifier_; }
65 
66   private:
67     int clientX_, clientY_;
68     int documentX_, documentY_;
69     int screenX_, screenY_;
70     int widgetX_, widgetY_;
71     long long identifier_;
72   };
73 
74 class WebRequest;
75 class WObject;
76 class WString;
77 
78 template<class E> class EventSignal;
79 
80 class WT_API JavaScriptEvent {
81 public:
82   // for mouse events:
83   int clientX, clientY;
84   int documentX, documentY;
85   int screenX, screenY;
86   int widgetX, widgetY;
87   int dragDX, dragDY;
88   int wheelDelta;
89 
90   // for key events or mouse event modifiers
91   int button;
92   int keyCode, charCode;
93   WFlags<KeyboardModifier> modifiers;
94 
95   // for touch events
96   std::vector<Touch> touches, targetTouches, changedTouches;
97 
98   // for gesture events
99   double scale, rotation;
100 
101   // for scroll events
102   int  scrollX, scrollY, viewportWidth, viewportHeight;
103 
104   // event type
105   std::string type;
106 
107   // target id
108   std::string tid;
109 
110   std::string response;
111 
112   std::vector<std::string> userEventArgs;
113 
114   void get(const WebRequest& request, const std::string& se);
115 
116   JavaScriptEvent();
117 };
118 
119 /*! \class WEvent Wt/WEvent.h Wt/WEvent.h
120  *  \brief An application event.
121  *
122  * The application is notified of an event (like a user interaction, a
123  * sesion timeout, an internal keep-alive event, or other event) using
124  * WApplication::notify().
125  *
126  * You can check for a particular event type using eventType().
127  */
128 class WT_API WEvent {
129 public:
130   struct Impl;
131 
132   /*! \brief Returns the event type.
133    */
134   EventType eventType() const;
135 
136 private:
WEvent(const Impl & impl)137   WEvent(const Impl& impl)
138     : impl_(impl)
139   { }
140 
141   const Impl& impl_;
142 
143   friend class WebSession;
144   friend class WebController;
145 };
146 
147 #ifdef WT_TARGET_JAVA
148 /*! \class WAbstractEvent Wt/WEvent.h Wt/WEvent.h
149  *  \brief Internal class WAbstractEvent.
150  */
151 class WAbstractEvent
152 {
153 public:
154   virtual WAbstractEvent *createFromJSEvent(const JavaScriptEvent& jsEvent) = 0;
155 };
156 #endif // WT_TARGET_JAVA
157 
158 
159 /*! \brief Enumeration for the mouse button.
160  */
161 enum class MouseButton {
162   None = 0,      //!< No button
163   Left = 1,    //!< Left button
164   Middle = 2,  //!< Middle button
165   Right = 4    //!< Right button
166 };
167 
168 /*! \class WMouseEvent Wt/WEvent.h Wt/WEvent.h
169  *  \brief A class providing details for a mouse event.
170  *
171  * \sa WInteractWidget::clicked(), WInteractWidget::doubleClicked(),
172  *     WInteractWidget::mouseWentDown(), WInteractWidget::mouseWentUp(),
173  *     WInteractWidget::mouseWentOver(), WInteractWidget::mouseMoved()
174  *
175  * \ingroup signalslot
176  */
177 class WT_API WMouseEvent
178 #ifdef WT_TARGET_JAVA
179                          : public WAbstractEvent
180 #endif // WT_TARGET_JAVA
181 {
182 public:
183   /*! \brief Typedef for enum Wt::MouseButton */
184   typedef MouseButton Button;
185 
186   /*! \brief Default constructor
187    */
188   WMouseEvent();
189 
190   /*! \brief Returns the button.
191    *
192    * If multiple buttons are currently pressed for a mouse moved or
193    * mouse dragged event, then the one with the smallest numerical value
194    * is returned.
195    */
196   MouseButton button() const;
197 
198   /*! \brief Returns keyboard modifiers.
199    *
200    * The result is a logical OR of \link Wt::KeyboardModifier
201    * KeyboardModifier\endlink flags.
202    */
modifiers()203   WFlags<KeyboardModifier> modifiers() const { return jsEvent_.modifiers; }
204 
205   /*! \brief Returns the mouse position relative to the document.
206    */
document()207   Coordinates document() const
208   { return Coordinates(jsEvent_.documentX, jsEvent_.documentY); }
209 
210   /*! \brief Returns the mouse position relative to the window.
211    *
212    * This differs from documentX() only through scrolling
213    * through the document.
214    */
window()215   Coordinates window() const
216   { return Coordinates(jsEvent_.clientX, jsEvent_.clientY); }
217 
218   /*! \brief Returns the mouse position relative to the screen.
219    */
screen()220   Coordinates screen() const
221   { return Coordinates(jsEvent_.screenX, jsEvent_.screenY); }
222 
223   /*! \brief Returns the mouse position relative to the widget.
224    */
widget()225   Coordinates widget() const
226   { return Coordinates(jsEvent_.widgetX, jsEvent_.widgetY); }
227 
228   /*! \brief Returns the distance over which the mouse has been dragged.
229    *
230    * This is only defined for a WInteractWidget::mouseWentUp() event.
231    */
dragDelta()232   Coordinates dragDelta() const
233   { return Coordinates(jsEvent_.dragDX, jsEvent_.dragDY); }
234 
235   /*! \brief Returns the scroll wheel delta.
236    *
237    * This is 1 when wheel was scrolled up or -1 when wheel was scrolled down.
238    *
239    * This is only defined for a WInteractWidget::mouseWheel() event.
240    */
wheelDelta()241   int wheelDelta() const { return jsEvent_.wheelDelta; }
242 
243 #ifdef WT_TARGET_JAVA
createFromJSEvent(const JavaScriptEvent & jsEvent)244   virtual WAbstractEvent *createFromJSEvent(const JavaScriptEvent& jsEvent)
245   {
246     return new WMouseEvent(jsEvent);
247   }
248 
249   static WMouseEvent templateEvent;
250 #endif // WT_TARGET_JAVA
251 
252   WMouseEvent(const JavaScriptEvent& jsEvent);
253 
254 protected:
255   JavaScriptEvent jsEvent_;
256 };
257 
258 /*! \class WKeyEvent Wt/WEvent.h Wt/WEvent.h
259  *  \brief A class providing details for a keyboard event.
260  *
261  * A key event is associated with the WInteractWidget::keyWentDown(),
262  * WInteractWidget::keyWentUp() and WInteractWidget::keyPressed()
263  * signals.
264  *
265  * \ingroup signalslot
266  */
267 class WT_API WKeyEvent
268 #ifdef WT_TARGET_JAVA
269                          : public WAbstractEvent
270 #endif // WT_TARGET_JAVA
271 {
272 public:
273   /*! \brief Default constructor
274    */
275   WKeyEvent();
276 
277   /*! \brief Returns the key code key that was pressed or released.
278    *
279    * The key code corresponds to the actual key on the keyboard,
280    * rather than the generated character.
281    *
282    * All three types of key events provide this information.
283    *
284    * \sa modifiers(), charCode()
285    */
286   Key key() const;
287 
288   /*! \brief Returns keyboard modifiers.
289    *
290    * The result is a logical OR of \link Wt::KeyboardModifier
291    * KeyboardModifier\endlink flags.
292    *
293    * All three types of key events provide this information.
294    *
295    * \sa key(), charCode()
296    */
modifiers()297   WFlags<KeyboardModifier> modifiers() const { return jsEvent_.modifiers; }
298 
299   /*! \brief Returns the unicode character code.
300    *
301    * This is only defined for a \link WInteractWidget::keyPressed
302    * keyPressed \endlink event, and returns the unicode character code point
303    * of a character that is entered.
304    *
305    * For the \link WInteractWidget::keyWentDown keyWentDown \endlink
306    * and \link WInteractWidget::keyWentUp keyWentUp \endlink events,
307    * '0' is returned.
308    *
309    * The charCode() may be different from key(). For example, a \link
310    * Wt::Key::M Key::M\endlink key may correspond to 'm' or 'M'
311    * character, depending on whether the shift key is pressed
312    * simultaneously.
313    *
314    * \sa key(), text()
315    */
316   int charCode() const;
317 
318   /*! \brief The (unicode) text that this key generated.
319    *
320    * This is only defined for a \link WInteractWidget::keyPressed
321    * keyPressed \endlink event, and returns a string that holds
322    * exactly one unicode character, which corresponds to charCode().
323    *
324    * For the \link WInteractWidget::keyWentDown keyWentDown \endlink
325    * and \link WInteractWidget::keyWentUp keyWentUp \endlink events,
326    * an empty string is returned.
327    *
328    * \sa charCode()
329    */
330   WT_USTRING text() const;
331 
332 #ifdef WT_TARGET_JAVA
createFromJSEvent(const JavaScriptEvent & jsEvent)333   virtual WAbstractEvent *createFromJSEvent(const JavaScriptEvent& jsEvent)
334   {
335     return new WKeyEvent(jsEvent);
336   }
337 
338   static WKeyEvent templateEvent;
339 #endif // WT_TARGET_JAVA
340 
341   WKeyEvent(const JavaScriptEvent& jsEvent);
342 
343 private:
344   JavaScriptEvent jsEvent_;
345 };
346 
347 /*! \class WDropEvent Wt/WEvent.h Wt/WEvent.h
348  *  \brief A class providing details for a drop event.
349  *
350  * \sa WWidget::dropEvent(WDropEvent)
351  *
352  * \ingroup signalslot
353  */
354 class WT_API WDropEvent
355 {
356 public:
357   /*! \brief The type of the original event.
358    */
359   enum class OriginalEventType {
360     Mouse, //!< The original event was a WMouseEvent
361     Touch //!< The original event was a WTouchEvent
362   };
363 
364   /*! \brief Constructor.
365    */
366   WDropEvent(WObject *source, const std::string& mimeType,
367 	     const WMouseEvent& mouseEvent);
368 
369   /*! \brief Constructor.
370    */
371   WDropEvent(WObject *source, const std::string& mimeType,
372 	     const WTouchEvent& touchEvent);
373 
374 #ifndef WT_TARGET_JAVA
375   WDropEvent(const WDropEvent &other);
376   WDropEvent &operator=(const WDropEvent &other);
377 #endif
378 
379   /*! \brief Returns the source of the drag&drop operation.
380    *
381    * The source is the widget that was set draggable using
382    * WInteractWidget::setDraggable().
383    */
source()384   WObject *source() const { return dropSource_; }
385 
386   /*! \brief Returns the mime type of this drop event.
387    */
mimeType()388   const std::string& mimeType() const { return dropMimeType_; }
389 
390   /*! \brief Returns the original mouse event.
391    *
392    * If eventType() == OriginalEventType::Mouse, this returns the original mouse event,
393    * otherwise this returns null.
394    */
mouseEvent()395   const WMouseEvent *mouseEvent() const { return mouseEvent_.get(); }
396 
397   /*! \brief Returns the original touch event.
398    *
399    * If eventType() == OriginalEventType::Touch, this returns the original touch event,
400    * otherwise this returns null.
401    */
touchEvent()402   const WTouchEvent *touchEvent() const { return touchEvent_.get(); }
403 
404   /*! \brief Returns the type of the original event.
405    */
originalEventType()406   OriginalEventType originalEventType() const { return mouseEvent_ ? OriginalEventType::Mouse : OriginalEventType::Touch; }
407 
408 private:
409   WObject            *dropSource_;
410   std::string         dropMimeType_;
411   std::unique_ptr<const WMouseEvent> mouseEvent_;
412   std::unique_ptr<const WTouchEvent> touchEvent_;
413 };
414 
415 /*! \class WScrollEvent Wt/WEvent.h Wt/WEvent.h
416  *  \brief A class providing details for a scroll event.
417  *
418  * \sa WContainerWidget::scrolled()
419  *
420  * \ingroup signalslot
421  */
422 class WT_API WScrollEvent
423 #ifdef WT_TARGET_JAVA
424                          : public WAbstractEvent
425 #endif // WT_TARGET_JAVA
426 {
427 public:
428   /*! \brief Default constructor
429    */
430   WScrollEvent();
431 
432   /*! \brief Returns the current horizontal scroll position.
433    *
434    * \sa scrollY(), viewportWidth()
435    */
scrollX()436   int scrollX() const { return jsEvent_.scrollX; }
437 
438   /*! \brief Returns the current vertical scroll position.
439    *
440    * \sa scrollX(), viewportHeight()
441    */
scrollY()442   int scrollY() const { return jsEvent_.scrollY; }
443 
444   /*! \brief Returns the current horizontal viewport width.
445    *
446    * Returns the current viewport width.
447    *
448    * \sa viewportHeight(), scrollX()
449    */
viewportWidth()450   int viewportWidth() const { return jsEvent_.viewportWidth; }
451 
452   /*! \brief Returns the current horizontal viewport height.
453    *
454    * Returns the current viewport height.
455    *
456    * \sa viewportWidth(), scrollY()
457    */
viewportHeight()458   int viewportHeight() const { return jsEvent_.viewportHeight; }
459 
460 #ifdef WT_TARGET_JAVA
createFromJSEvent(const JavaScriptEvent & jsEvent)461   virtual WAbstractEvent *createFromJSEvent(const JavaScriptEvent& jsEvent)
462   {
463     return new WScrollEvent(jsEvent);
464   }
465 
466   static WScrollEvent templateEvent;
467 #endif // WT_TARGET_JAVA
468 
469 private:
470   JavaScriptEvent jsEvent_;
471 
472   WScrollEvent(const JavaScriptEvent& jsEvent);
473 
474   friend class EventSignal<WScrollEvent>;
475 };
476 
477 /*! \class WTouchEvent Wt/WEvent.h Wt/WEvent.h
478  *  \brief A class providing details for a touch event.
479  *
480  * \sa WInteractWidget::touchStarted(), WInteractWidget::touchMoved(),
481  *     WInteractWidget::touchEnded()
482  *
483  * \ingroup signalslot
484  */
485 class WT_API WTouchEvent
486 #ifdef WT_TARGET_JAVA
487                          : public WAbstractEvent
488 #endif // WT_TARGET_JAVA
489 {
490 public:
491   /*! \brief Default constructor
492    */
493   WTouchEvent();
494 
495   /*! \brief Returns a list of \link Touch\endlink objects for every finger
496    *         currently touching the screen.
497    */
touches()498   const std::vector<Touch>& touches() const
499     { return jsEvent_.touches; }
500 
501   /*! \brief Returns a list of \link Touch\endlink objects for finger touches
502    *         that started out within the same widget.
503    */
targetTouches()504   const std::vector<Touch>& targetTouches() const
505     { return jsEvent_.targetTouches; }
506 
507   /*! \brief Returns a list of \link Touch\endlink objects for every finger
508    *         involved in the event.
509    */
changedTouches()510   const std::vector<Touch>& changedTouches() const
511     { return jsEvent_.changedTouches; }
512 
513 #ifdef WT_TARGET_JAVA
createFromJSEvent(const JavaScriptEvent & jsEvent)514   virtual WAbstractEvent *createFromJSEvent(const JavaScriptEvent& jsEvent)
515   {
516     return new WTouchEvent(jsEvent);
517   }
518 
519   static WTouchEvent templateEvent;
520 #endif // WT_TARGET_JAVA
521 
522   WTouchEvent(const JavaScriptEvent& jsEvent);
523 
524 protected:
525   JavaScriptEvent jsEvent_;
526 };
527 
528 /*! \class WGestureEvent Wt/WEvent.h Wt/WEvent.h
529  *  \brief A class providing details for a gesture event.
530  *
531  * \sa WInteractWidget::gestureStarted(), WInteractWidget::gestureChanged(),
532  *     WInteractWidget::gestureEnded()
533  *
534  * \ingroup signalslot
535  */
536 class WT_API WGestureEvent
537 #ifdef WT_TARGET_JAVA
538                          : public WAbstractEvent
539 #endif // WT_TARGET_JAVA
540 {
541 public:
542   /*! \brief Default constructor
543    */
544   WGestureEvent();
545 
546   /*! \brief Returns the multiplier which the user has pinched or pushed
547              (relative to 1).
548    */
scale()549   double scale() const { return jsEvent_.scale; }
550 
551   /*! \brief Returns the number of degrees the user has rotated his/her fingers.
552    */
rotation()553   double rotation() const { return jsEvent_.rotation; }
554 
555 #ifdef WT_TARGET_JAVA
createFromJSEvent(const JavaScriptEvent & jsEvent)556   virtual WAbstractEvent *createFromJSEvent(const JavaScriptEvent& jsEvent)
557   {
558     return new WGestureEvent(jsEvent);
559   }
560 
561   static WGestureEvent templateEvent;
562 #endif // WT_TARGET_JAVA
563 
564   WGestureEvent(const JavaScriptEvent& jsEvent);
565 
566 protected:
567   JavaScriptEvent jsEvent_;
568 };
569 
570 }
571 
572 #endif // WEVENT_H_
573