The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
6.0KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. struct CustomMouseCursorInfo
  20. {
  21. CustomMouseCursorInfo (const Image& im, int hsX, int hsY) noexcept
  22. : image (im), hotspot (hsX, hsY), scaleFactor (1.0f)
  23. {}
  24. CustomMouseCursorInfo (const Image& im, Point<int> hs, float scale) noexcept
  25. : image (im), hotspot (hs), scaleFactor (scale)
  26. {}
  27. void* create() const;
  28. Image image;
  29. const Point<int> hotspot;
  30. float scaleFactor;
  31. private:
  32. JUCE_DECLARE_NON_COPYABLE (CustomMouseCursorInfo)
  33. };
  34. class MouseCursor::SharedCursorHandle
  35. {
  36. public:
  37. explicit SharedCursorHandle (const MouseCursor::StandardCursorType type)
  38. : handle (createStandardMouseCursor (type)),
  39. refCount (1),
  40. standardType (type),
  41. isStandard (true)
  42. {
  43. }
  44. SharedCursorHandle (const Image& image, Point<int> hotSpot, const float scaleFactor)
  45. : handle (CustomMouseCursorInfo (image, hotSpot, scaleFactor).create()),
  46. refCount (1),
  47. standardType (MouseCursor::NormalCursor),
  48. isStandard (false)
  49. {
  50. }
  51. ~SharedCursorHandle()
  52. {
  53. deleteMouseCursor (handle, isStandard);
  54. }
  55. static SharedCursorHandle* createStandard (const MouseCursor::StandardCursorType type)
  56. {
  57. jassert (isPositiveAndBelow (type, MouseCursor::NumStandardCursorTypes));
  58. const SpinLock::ScopedLockType sl (lock);
  59. SharedCursorHandle*& c = getSharedCursor (type);
  60. if (c == nullptr)
  61. c = new SharedCursorHandle (type);
  62. else
  63. c->retain();
  64. return c;
  65. }
  66. bool isStandardType (MouseCursor::StandardCursorType type) const noexcept
  67. {
  68. return type == standardType && isStandard;
  69. }
  70. SharedCursorHandle* retain() noexcept
  71. {
  72. ++refCount;
  73. return this;
  74. }
  75. void release()
  76. {
  77. if (--refCount == 0)
  78. {
  79. if (isStandard)
  80. {
  81. const SpinLock::ScopedLockType sl (lock);
  82. getSharedCursor (standardType) = nullptr;
  83. }
  84. delete this;
  85. }
  86. }
  87. void* getHandle() const noexcept { return handle; }
  88. private:
  89. void* const handle;
  90. Atomic <int> refCount;
  91. const MouseCursor::StandardCursorType standardType;
  92. const bool isStandard;
  93. static SpinLock lock;
  94. static SharedCursorHandle*& getSharedCursor (const MouseCursor::StandardCursorType type)
  95. {
  96. static SharedCursorHandle* cursors [MouseCursor::NumStandardCursorTypes] = {};
  97. return cursors [type];
  98. }
  99. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedCursorHandle)
  100. };
  101. SpinLock MouseCursor::SharedCursorHandle::lock;
  102. //==============================================================================
  103. MouseCursor::MouseCursor() noexcept
  104. : cursorHandle (nullptr)
  105. {
  106. }
  107. MouseCursor::MouseCursor (const StandardCursorType type)
  108. : cursorHandle (type != MouseCursor::NormalCursor ? SharedCursorHandle::createStandard (type) : nullptr)
  109. {
  110. }
  111. MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY)
  112. : cursorHandle (new SharedCursorHandle (image, Point<int> (hotSpotX, hotSpotY), 1.0f))
  113. {
  114. }
  115. MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY, float scaleFactor)
  116. : cursorHandle (new SharedCursorHandle (image, Point<int> (hotSpotX, hotSpotY), scaleFactor))
  117. {
  118. }
  119. MouseCursor::MouseCursor (const MouseCursor& other)
  120. : cursorHandle (other.cursorHandle == nullptr ? nullptr : other.cursorHandle->retain())
  121. {
  122. }
  123. MouseCursor::~MouseCursor()
  124. {
  125. if (cursorHandle != nullptr)
  126. cursorHandle->release();
  127. }
  128. MouseCursor& MouseCursor::operator= (const MouseCursor& other)
  129. {
  130. if (other.cursorHandle != nullptr)
  131. other.cursorHandle->retain();
  132. if (cursorHandle != nullptr)
  133. cursorHandle->release();
  134. cursorHandle = other.cursorHandle;
  135. return *this;
  136. }
  137. MouseCursor::MouseCursor (MouseCursor&& other) noexcept
  138. : cursorHandle (other.cursorHandle)
  139. {
  140. other.cursorHandle = nullptr;
  141. }
  142. MouseCursor& MouseCursor::operator= (MouseCursor&& other) noexcept
  143. {
  144. std::swap (cursorHandle, other.cursorHandle);
  145. return *this;
  146. }
  147. bool MouseCursor::operator== (const MouseCursor& other) const noexcept
  148. {
  149. return getHandle() == other.getHandle();
  150. }
  151. bool MouseCursor::operator== (StandardCursorType type) const noexcept
  152. {
  153. return cursorHandle != nullptr ? cursorHandle->isStandardType (type)
  154. : (type == NormalCursor);
  155. }
  156. bool MouseCursor::operator!= (const MouseCursor& other) const noexcept { return ! operator== (other); }
  157. bool MouseCursor::operator!= (StandardCursorType type) const noexcept { return ! operator== (type); }
  158. void* MouseCursor::getHandle() const noexcept
  159. {
  160. return cursorHandle != nullptr ? cursorHandle->getHandle() : nullptr;
  161. }
  162. void MouseCursor::showWaitCursor()
  163. {
  164. Desktop::getInstance().getMainMouseSource().showMouseCursor (MouseCursor::WaitCursor);
  165. }
  166. void MouseCursor::hideWaitCursor()
  167. {
  168. Desktop::getInstance().getMainMouseSource().revealCursor();
  169. }