BsDragAndDropManager.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsPrerequisites.h"
  5. #include "BsModule.h"
  6. #include "BsInput.h"
  7. #include "BsEvent.h"
  8. #include <atomic>
  9. namespace BansheeEngine
  10. {
  11. /** @cond INTERNAL */
  12. /** @addtogroup GUI
  13. * @{
  14. */
  15. /** Holds data returned by DragAndDropManager callbacks. */
  16. struct BS_EXPORT DragCallbackInfo
  17. {
  18. DragCallbackInfo()
  19. :processed(false)
  20. { }
  21. bool processed;
  22. };
  23. /**
  24. * Handles GUI drag and drop operations. When active GUI elements will be notified of any drag events and will be able
  25. * to retrieve dragged data.
  26. *
  27. * @note Sim thread only.
  28. */
  29. class BS_EXPORT DragAndDropManager : public Module<DragAndDropManager>
  30. {
  31. public:
  32. DragAndDropManager();
  33. ~DragAndDropManager();
  34. /**
  35. * Starts a drag operation of the specified type. This means GUI elements will start receiving drag and drop
  36. * related events and they may choose to handle them.
  37. *
  38. * @param[in] typeId Type of the drag and drop operation that other objects may query and decide
  39. * if they want to handle it. User defined.
  40. * @param[in] data Some operation specific data that is just passed through to however needs it.
  41. * @param[in] dropCallback The drop callback that gets triggered whenever mouse button is released and
  42. * drag operation ends. You should perform any cleanup here.
  43. * @param[in] needsValidDropTarget (optional) Determines whether the drop operation may happen anywhere or
  44. * does the GUI element need to specifically accept the drag of this type.
  45. * If false all GUI elements we mouse over will receive drag/drop events,
  46. * otherwise only those that specifically subscribe to the specified drag
  47. * operation of this typeId will.
  48. * Additionally this will determine the cursor displayed (whether or not it
  49. * can have a "denied" state).
  50. */
  51. void startDrag(UINT32 typeId, void* data, std::function<void(bool)> dropCallback, bool needsValidDropTarget = false);
  52. /** Returns true if drag is currently in progress. */
  53. bool isDragInProgress() const { return mIsDragInProgress; }
  54. /** Get type ID of drag currently in progress. Only valid if drag is in progress. */
  55. UINT32 getDragTypeId() const { return mDragTypeId; }
  56. /** Gets drag specific data specified when the drag started. Only valid if drag is in progress. */
  57. void* getDragData() const { return mData; }
  58. /**
  59. * Determines whether the drop operation may happen anywhere or does the GUI element need to specifically accept the
  60. * drag of this type. If false all GUI elements we mouse over will receive drag/drop events, otherwise only those
  61. * that specifically subscribe to the specified drag operation of this typeId will.
  62. *
  63. * Additionally this will determine the cursor displayed (whether or not it can have a "denied" state).
  64. */
  65. bool needsValidDropTarget() const { return mNeedsValidDropTarget; }
  66. /**
  67. * Registers a new callback that will be triggered when dragged item is dropped. Provided parameter specifies if
  68. * the drop operation was handled by anyone or not.
  69. */
  70. void addDropCallback(std::function<void(bool)> dropCallback);
  71. /** Called once per frame. Checks if drag ended or if window loses focus. */
  72. void _update();
  73. /**
  74. * Triggers a callback when user releases the pointer and the drag operation ends. Provided parameters inform the
  75. * subscriber where the pointer was released, and allows the subscriber to note whether the drag operation was
  76. * processed or not.
  77. *
  78. * @note Internal event. You should use addDropCallback for normal use.
  79. */
  80. Event<void(const PointerEvent&, DragCallbackInfo&)> onDragEnded;
  81. private:
  82. /** Triggers any drop callbacks and clears callback data. */
  83. void endDrag(bool processed);
  84. /**
  85. * Called by the core thread whenever mouse capture state changes. This can happen when window loses focus
  86. * (for example alt+tab). In that case we want to end the drag even if the user is still holding the dragged item.
  87. *
  88. * @note Core thread.
  89. */
  90. void mouseCaptureChanged();
  91. /** Called by the input system when pointer is released. */
  92. void cursorReleased(const PointerEvent& event);
  93. private:
  94. UINT32 mDragTypeId;
  95. void* mData;
  96. Vector<std::function<void(bool)>> mDropCallbacks;
  97. bool mIsDragInProgress;
  98. bool mNeedsValidDropTarget;
  99. HEvent mMouseCaptureChangedConn;
  100. std::atomic<bool> mCaptureChanged;
  101. std::atomic<int> mCaptureActive;
  102. std::atomic<UINT64> mCaptureChangeFrame;
  103. };
  104. /** @} */
  105. /** @endcond */
  106. }