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 WINTERACT_WIDGET_H_ 8 #define WINTERACT_WIDGET_H_ 9 10 #include <Wt/WWebWidget.h> 11 #include <Wt/WEvent.h> 12 13 namespace Wt { 14 15 class JSlot; 16 17 /*! \class WInteractWidget Wt/WInteractWidget.h Wt/WInteractWidget.h 18 * \brief An abstract widget that can receive user-interface interaction 19 * 20 * This abstract widget provides access to event signals that 21 * correspond to user-interface interaction through mouse or keyboard. 22 * 23 * When JavaScript is disabled, only the clicked() event will 24 * propagate (but without event details information). 25 * 26 * <h3>CSS</h3> 27 * 28 * Styling through CSS is not applicable. 29 */ 30 class WT_API WInteractWidget : public WWebWidget 31 { 32 public: 33 /*! \brief Create an InteractWidget. 34 */ 35 WInteractWidget(); 36 37 ~WInteractWidget(); 38 39 /*! \brief Event signal emitted when a keyboard key is pushed down. 40 * 41 * The keyWentDown signal is the first signal emitted when a key is 42 * pressed (before the keyPressed signal). Unlike keyPressed() 43 * however it is also emitted for modifier keys (such as "shift", 44 * "control", ...) or keyboard navigation keys that do not have a 45 * corresponding character. 46 * 47 * Form widgets (like WLineEdit) will receive key events when 48 * focussed. Other widgets will receive key events when they contain 49 * (directly or indirectly) a form widget that has focus. 50 * 51 * To capture a key down event when no element has focus, see 52 * WApplication::globalKeyWentDown() 53 * 54 * \sa keyPressed(), keyWentUp() 55 */ 56 EventSignal<WKeyEvent>& keyWentDown(); 57 58 /*! \brief Event signal emitted when a "character" was entered. 59 * 60 * The keyPressed signal is emitted when a key is pressed, and a 61 * character is entered. Unlike keyWentDown(), it is emitted only 62 * for key presses that result in a character being entered, and 63 * thus not for modifier keys or keyboard navigation keys. 64 * 65 * Form widgets (like WLineEdit) will receive key events when 66 * focussed. Other widgets will receive key events when they contain 67 * (directly or indirectly) a form widget that has focus. 68 * 69 * To capture a key press when no element has focus, see 70 * WApplication::globalKeyPressed() 71 * 72 * \sa keyWentDown() 73 */ 74 EventSignal<WKeyEvent>& keyPressed(); 75 76 /*! \brief Event signal emitted when a keyboard key is released. 77 * 78 * This is the counter-part of the keyWentDown() event. Every 79 * key-down has its corresponding key-up. 80 * 81 * Form widgets (like WLineEdit) will receive key events when 82 * focussed. Other widgets will receive key events when they contain 83 * (directly or indirectly) a form widget that has focus. 84 * 85 * To capture a key up event when no element has focus, see 86 * WApplication::globalKeyWentUp() 87 * 88 * \sa keyWentDown() 89 */ 90 EventSignal<WKeyEvent>& keyWentUp(); 91 92 /*! \brief Event signal emitted when enter was pressed. 93 * 94 * This signal is emitted when the Enter or Return key was pressed. 95 * 96 * Form widgets (like WLineEdit) will receive key events when 97 * focussed. Other widgets will receive key events when they contain 98 * (directly or indirectly) a form widget that has focus. 99 * 100 * To capture an enter press when no element has focus, see 101 * WApplication::globalEnterPressed() 102 * 103 * \sa keyPressed(), Key::Enter 104 */ 105 EventSignal<>& enterPressed(); 106 107 /*! \brief Event signal emitted when escape was pressed. 108 * 109 * This signal is emitted when the Escape key was pressed. 110 * 111 * Form widgets (like WLineEdit) will receive key events when 112 * focussed. Other widgets will receive key events when they contain 113 * (directly or indirectly) a form widget that has focus. 114 * 115 * To capture an escape press when no element has focus, see 116 * WApplication::globalEscapePressed() 117 * 118 * \sa keyPressed(), Key::Escape 119 */ 120 EventSignal<>& escapePressed(); 121 122 /*! \brief Event signal emitted when the primary mouse button was clicked on this 123 * widget. 124 * 125 * The event details contains information such as the \link 126 * WMouseEvent::button button\endlink, optional \link 127 * WMouseEvent::modifiers() keyboard modifiers\endlink, and mouse 128 * coordinates relative to the \link WMouseEvent::widget() 129 * widget\endlink, the window \link WMouseEvent::window() 130 * window\endlink, or the \link WMouseEvent::document() 131 * document\endlink. 132 * 133 * For more details, see the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event). 134 * 135 * \note When JavaScript is disabled, the event details contain 136 * invalid information. 137 */ 138 EventSignal<WMouseEvent>& clicked(); 139 140 /*! \brief Event signal emitted when the primary mouse button was double clicked 141 * on this widget. 142 * 143 * The event details contains information such as the \link 144 * WMouseEvent::button button\endlink, optional \link 145 * WMouseEvent::modifiers() keyboard modifiers\endlink, and mouse 146 * coordinates relative to the \link WMouseEvent::widget() 147 * widget\endlink, the window \link WMouseEvent::window() 148 * window\endlink, or the \link WMouseEvent::document() 149 * document\endlink. 150 * 151 * For more details, see the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event). 152 * 153 * \note When JavaScript is disabled, the signal will never fire. 154 */ 155 EventSignal<WMouseEvent>& doubleClicked(); 156 157 /*! \brief Event signal emitted when a mouse button was pushed down on this 158 * widget. 159 * 160 * The event details contains information such as the \link 161 * WMouseEvent::button button\endlink, optional \link 162 * WMouseEvent::modifiers() keyboard modifiers\endlink, and mouse 163 * coordinates relative to the \link WMouseEvent::widget() 164 * widget\endlink, the window \link WMouseEvent::window() 165 * window\endlink, or the \link WMouseEvent::document() 166 * document\endlink. 167 * 168 * \note When JavaScript is disabled, the signal will never fire. 169 */ 170 EventSignal<WMouseEvent>& mouseWentDown(); 171 172 /*! \brief Event signal emitted when a mouse button was released on this 173 * widget. 174 * 175 * The event details contains information such as the \link 176 * WMouseEvent::button button\endlink, optional \link 177 * WMouseEvent::modifiers() keyboard modifiers\endlink, and mouse 178 * coordinates relative to the \link WMouseEvent::widget() 179 * widget\endlink, the window \link WMouseEvent::window() 180 * window\endlink, or the \link WMouseEvent::document() 181 * document\endlink. 182 * 183 * If you connect also the mouseWentDown() signal, then a subsequent 184 * mouseWentUp() will be received by the same widget, even if mouse is 185 * no longer over the original widget. 186 * 187 * \note When JavaScript is disabled, the signal will never fire. 188 */ 189 EventSignal<WMouseEvent>& mouseWentUp(); 190 191 /*! \brief Event signal emitted when the mouse went out of this widget. 192 * 193 * \note When JavaScript is disabled, the signal will never fire. 194 */ 195 EventSignal<WMouseEvent>& mouseWentOut(); 196 197 /*! \brief Event signal emitted when the mouse entered this widget. 198 * 199 * The signal is emitted as soon as the mouse enters the widget, or 200 * after some delay as configured by setMouseOverDelay() 201 * 202 * \note When JavaScript is disabled, the signal will never fire. 203 */ 204 EventSignal<WMouseEvent>& mouseWentOver(); 205 206 /*! \brief Event signal emitted when the mouse moved over this widget. 207 * 208 * The mouse event contains information on the button(s) currently 209 * pressed. If multiple buttons are currently pressed, only the 210 * button with smallest enum value is returned. 211 * 212 * \note When JavaScript is disabled, the signal will never fire. 213 */ 214 EventSignal<WMouseEvent>& mouseMoved(); 215 216 /*! \brief Event signal emitted when the mouse is dragged over this widget. 217 * 218 * The mouse event contains information on the button(s) currently 219 * pressed. If multiple buttons are currently pressed, only the 220 * button with smallest enum value is returned. 221 * 222 * \note When JavaScript is disabled, the signal will never fire. 223 */ 224 EventSignal<WMouseEvent>& mouseDragged(); 225 226 /*! \brief Event signal emitted when the mouse scroll wheel was used. 227 * 228 * The event details contains information such as the \link 229 * WMouseEvent::wheelDelta() wheel delta\endlink, optional \link 230 * WMouseEvent::modifiers() keyboard modifiers\endlink, and mouse 231 * coordinates relative to the \link WMouseEvent::widget() 232 * widget\endlink, the window \link WMouseEvent::window() 233 * window\endlink, or the \link WMouseEvent::document() 234 * document\endlink. 235 * 236 * \note When JavaScript is disabled, the signal will never fire. 237 */ 238 EventSignal<WMouseEvent>& mouseWheel(); 239 240 /*! \brief Event signal emitted when a finger is placed on the screen. 241 * 242 * The event details contains information such as the \link 243 * WTouchEvent::touches() touches\endlink, \link WTouchEvent::targetTouches() 244 * target touches\endlink and \link WTouchEvent::changedTouches() changed 245 * touches\endlink. 246 * 247 * \note When JavaScript is disabled, the signal will never fire. 248 */ 249 EventSignal<WTouchEvent>& touchStarted(); 250 251 /*! \brief Event signal emitted when a finger is removed from the screen. 252 * 253 * The event details contains information such as the \link 254 * WTouchEvent::touches() touches\endlink, \link WTouchEvent::targetTouches() 255 * target touches\endlink and \link WTouchEvent::changedTouches() changed 256 * touches\endlink. 257 * 258 * \note When JavaScript is disabled, the signal will never fire. 259 */ 260 EventSignal<WTouchEvent>& touchEnded(); 261 262 /*! \brief Event signal emitted when a finger, which is already placed on the 263 * screen, is moved across the screen. 264 * 265 * The event details contains information such as the \link 266 * WTouchEvent::touches() touches\endlink, \link WTouchEvent::targetTouches() 267 * target touches\endlink and \link WTouchEvent::changedTouches() changed 268 * touches\endlink. 269 * 270 * \note When JavaScript is disabled, the signal will never fire. 271 */ 272 EventSignal<WTouchEvent>& touchMoved(); 273 274 /*! \brief Event signal emitted when a gesture is started. 275 * 276 * The event details contains information about the \link 277 * WGestureEvent::scale() scale\endlink and the \link 278 * WGestureEvent::rotation() rotation\endlink. 279 * 280 * \note When JavaScript is disabled, the signal will never fire. 281 */ 282 EventSignal<WGestureEvent>& gestureStarted(); 283 284 /*! \brief Event signal emitted when a gesture is changed. 285 * 286 * The event details contains information about the \link 287 * WGestureEvent::scale() scale\endlink and the \link 288 * WGestureEvent::rotation() rotation\endlink. 289 * 290 * \note When JavaScript is disabled, the signal will never fire. 291 */ 292 EventSignal<WGestureEvent>& gestureChanged(); 293 294 /*! \brief Event signal emitted when a gesture is ended. 295 * 296 * The event details contains information about the \link 297 * WGestureEvent::scale() scale\endlink and the \link 298 * WGestureEvent::rotation() rotation\endlink. 299 * 300 * \note When JavaScript is disabled, the signal will never fire. 301 */ 302 EventSignal<WGestureEvent>& gestureEnded(); 303 304 /*! \brief Configure dragging for drag and drop. 305 * 306 * Enable drag&drop for this widget. The mimeType is used to find a 307 * suitable drop target, which must accept dropping of this mimetype. 308 * 309 * By default, the entire widget is dragged. One may specify another 310 * widget to be dragged (for example the parent as \p dragWidget) or 311 * a \p dragWidget whose function is only to represent the drag 312 * visually (when \p isDragWidgetOnly = \c true). 313 * 314 * The widget to be identified as source in the dropEvent may be given 315 * explicitly, and will default to this widget otherwise. 316 * 317 * When using a touch interface, the widget can also be dragged after 318 * a long press. 319 * 320 * \note When JavaScript is disabled, drag&drop does not work. 321 * 322 * \sa WWidget::dropEvent(), WWidget::acceptDrops(), WDropEvent 323 */ 324 void setDraggable(const std::string& mimeType, 325 WWidget *dragWidget = nullptr, 326 bool isDragWidgetOnly = false, 327 WObject *sourceWidget = nullptr); 328 329 /*! \brief Disable drag & drop for this widget. 330 * 331 * \sa setDraggable() 332 */ 333 void unsetDraggable(); 334 335 /*! \brief Sets a delay for the mouse over event. 336 * 337 * This sets a delay (in milliseconds) before the mouse over event 338 * is emitted. 339 * 340 * The default value is 0. 341 * 342 * \sa mouseWentOver() 343 */ 344 void setMouseOverDelay(int delay); 345 346 /*! \brief Returns the mouse over signal delay. 347 * 348 * \sa setMouseOverDelay() 349 */ 350 int mouseOverDelay() const; 351 352 virtual void setPopup(bool popup) override; 353 virtual void load() override; 354 virtual bool isEnabled() const override; 355 356 protected: 357 virtual void updateDom(DomElement& element, bool all) override; 358 virtual void propagateRenderOk(bool deep) override; 359 virtual void propagateSetEnabled(bool enabled) override; 360 361 void updateEventSignals(DomElement& element, bool all); 362 363 std::unique_ptr<JSlot> dragSlot_; 364 std::unique_ptr<JSlot> dragTouchSlot_; 365 std::unique_ptr<JSlot> dragTouchEndSlot_; 366 367 protected: 368 // also used in WAbstractToggleButton 369 static const char *M_CLICK_SIGNAL; 370 371 private: 372 static const char *CLICK_SIGNAL; 373 static const char *KEYDOWN_SIGNAL; 374 static const char *KEYPRESS_SIGNAL; 375 static const char *KEYUP_SIGNAL; 376 static const char *ENTER_PRESS_SIGNAL; 377 static const char *ESCAPE_PRESS_SIGNAL; 378 static const char *DBL_CLICK_SIGNAL; 379 static const char *MOUSE_DOWN_SIGNAL; 380 static const char *MOUSE_UP_SIGNAL; 381 static const char *MOUSE_OUT_SIGNAL; 382 static const char *MOUSE_OVER_SIGNAL; 383 static const char *MOUSE_MOVE_SIGNAL; 384 static const char *MOUSE_DRAG_SIGNAL; 385 static const char *MOUSE_WHEEL_SIGNAL; 386 static const char *WHEEL_SIGNAL; 387 static const char *TOUCH_START_SIGNAL; 388 static const char *TOUCH_MOVE_SIGNAL; 389 static const char *TOUCH_END_SIGNAL; 390 static const char *GESTURE_START_SIGNAL; 391 static const char *GESTURE_CHANGE_SIGNAL; 392 static const char *GESTURE_END_SIGNAL; 393 static const char *DRAGSTART_SIGNAL; 394 395 friend class DomElement; 396 friend class WAbstractToggleButton; 397 friend class WWebWidget; 398 399 int mouseOverDelay_; 400 }; 401 402 } 403 404 #endif // WINTERACT_WIDGET_H_ 405