BsDragAndDropManager.h 4.8 KB

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