InputEvent.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // zlib open source license
  2. //
  3. // Copyright (c) 2018 to 2019 David Forsgren Piuva
  4. //
  5. // This software is provided 'as-is', without any express or implied
  6. // warranty. In no event will the authors be held liable for any damages
  7. // arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it
  11. // freely, subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented; you must not
  14. // claim that you wrote the original software. If you use this software
  15. // in a product, an acknowledgment in the product documentation would be
  16. // appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such, and must not be
  19. // misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source
  22. // distribution.
  23. #ifndef DFPSR_GUI_INPUT_EVENT
  24. #define DFPSR_GUI_INPUT_EVENT
  25. #include "../math/IVector.h"
  26. #include <functional>
  27. namespace dsr {
  28. class InputEvent {
  29. public:
  30. InputEvent() {}
  31. virtual ~InputEvent() {}
  32. };
  33. enum class KeyboardEventType { KeyDown, KeyUp, KeyType };
  34. // The DsrKey enumeration is convertible to integers allow certain well defined math operations
  35. // Safe assumptions:
  36. // * DsrKey_0 to DsrKey_9 are guaranteed to be in an increasing serial order (so that "key - DsrKey_0" is the key's number)
  37. // * DsrKey_F1 to DsrKey_F12 are guaranteed to be in an increasing serial order (so that "key - (DsrKey_F1 - 1)" is the key's number)
  38. // * DsrKey_A to DsrKey_Z are guaranteed to be in an increasing serial order
  39. enum DsrKey {
  40. DsrKey_LeftArrow, DsrKey_RightArrow, DsrKey_UpArrow, DsrKey_DownArrow,
  41. DsrKey_LeftControl, DsrKey_RightControl, DsrKey_LeftShift, DsrKey_RightShift, DsrKey_LeftAlt, DsrKey_RightAlt,
  42. DsrKey_Escape, DsrKey_Pause, DsrKey_Space, DsrKey_Tab, DsrKey_Return, DsrKey_BackSpace, DsrKey_Delete,
  43. DsrKey_0, DsrKey_1, DsrKey_2, DsrKey_3, DsrKey_4, DsrKey_5, DsrKey_6, DsrKey_7, DsrKey_8, DsrKey_9,
  44. DsrKey_F1, DsrKey_F2, DsrKey_F3, DsrKey_F4, DsrKey_F5, DsrKey_F6, DsrKey_F7, DsrKey_F8, DsrKey_F9, DsrKey_F10, DsrKey_F11, DsrKey_F12,
  45. DsrKey_A, DsrKey_B, DsrKey_C, DsrKey_D, DsrKey_E, DsrKey_F, DsrKey_G, DsrKey_H, DsrKey_I, DsrKey_J, DsrKey_K, DsrKey_L, DsrKey_M,
  46. DsrKey_N, DsrKey_O, DsrKey_P, DsrKey_Q, DsrKey_R, DsrKey_S, DsrKey_T, DsrKey_U, DsrKey_V, DsrKey_W, DsrKey_X, DsrKey_Y, DsrKey_Z,
  47. // TODO: Add any missing essential keys.
  48. DsrKey_Unhandled
  49. };
  50. inline String getName(DsrKey v);
  51. String& string_toStreamIndented(String& target, const DsrKey& source, const ReadableString& indentation);
  52. class KeyboardEvent : public InputEvent {
  53. public:
  54. // What the user did to the key
  55. KeyboardEventType keyboardEventType;
  56. // Actual characters for non-latin characters
  57. char character;
  58. // Minimal set of keys for portability
  59. DsrKey dsrKey;
  60. KeyboardEvent(KeyboardEventType keyboardEventType, char character, DsrKey dsrKey)
  61. : keyboardEventType(keyboardEventType), character(character), dsrKey(dsrKey) {}
  62. };
  63. enum class MouseKeyEnum { NoKey, Left, Right, Middle, ScrollUp, ScrollDown };
  64. enum class MouseEventType { MouseDown, MouseUp, MouseMove, Scroll };
  65. class MouseEvent : public InputEvent {
  66. public:
  67. MouseEventType mouseEventType;
  68. MouseKeyEnum key;
  69. IVector2D position; // Pixel coordinates relative to upper left corner of parent container
  70. MouseEvent(MouseEventType mouseEventType, MouseKeyEnum key, IVector2D position)
  71. : mouseEventType(mouseEventType), key(key), position(position) {}
  72. };
  73. inline MouseEvent operator+(const MouseEvent &old, const IVector2D &offset) {
  74. MouseEvent result = old;
  75. result.position = result.position + offset;
  76. return result;
  77. }
  78. inline MouseEvent operator-(const MouseEvent &old, const IVector2D &offset) {
  79. MouseEvent result = old;
  80. result.position = result.position - offset;
  81. return result;
  82. }
  83. inline MouseEvent operator*(const MouseEvent &old, int scale) {
  84. MouseEvent result = old;
  85. result.position = result.position * scale;
  86. return result;
  87. }
  88. inline MouseEvent operator/(const MouseEvent &old, int scale) {
  89. MouseEvent result = old;
  90. result.position = result.position / scale;
  91. return result;
  92. }
  93. enum class WindowEventType { Close, Redraw };
  94. class WindowEvent : public InputEvent {
  95. public:
  96. WindowEventType windowEventType;
  97. int width, height;
  98. WindowEvent(WindowEventType windowEventType, int width, int height)
  99. : windowEventType(windowEventType), width(width), height(height) {}
  100. };
  101. // A macro for declaring a virtual callback from the base method
  102. // Use the getter for registering methods so that they can be forwarded to a wrapper without inheritance
  103. // Use the actual variable beginning with `callback_` when calling the method from inside
  104. #define DECLARE_CALLBACK(NAME, LAMBDA) \
  105. decltype(LAMBDA) callback_##NAME = LAMBDA; \
  106. decltype(LAMBDA)& NAME() { return callback_##NAME; }
  107. // The callback templates and types
  108. static std::function<void()> emptyCallback = []() {};
  109. using EmptyCallback = decltype(emptyCallback) ;
  110. static std::function<void(int)> indexCallback = [](int64_t index) {};
  111. using IndexCallback = decltype(indexCallback);
  112. static std::function<void(int, int)> sizeCallback = [](int width, int height) {};
  113. using SizeCallback = decltype(sizeCallback);
  114. static std::function<void(const KeyboardEvent&)> keyboardCallback = [](const KeyboardEvent& event) {};
  115. using KeyboardCallback = decltype(keyboardCallback);
  116. static std::function<void(const MouseEvent&)> mouseCallback = [](const MouseEvent& event) {};
  117. using MouseCallback = decltype(mouseCallback);
  118. }
  119. #endif