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.

214 lines
6.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. struct CustomMouseCursorInfo
  19. {
  20. CustomMouseCursorInfo (const Image& im, int hsX, int hsY) noexcept
  21. : image (im), hotspot (hsX, hsY), scaleFactor (1.0f)
  22. {}
  23. CustomMouseCursorInfo (const Image& im, const Point<int>& hs, float scale) noexcept
  24. : image (im), hotspot (hs), scaleFactor (scale)
  25. {}
  26. void* create() const;
  27. Image image;
  28. const Point<int> hotspot;
  29. float scaleFactor;
  30. };
  31. class MouseCursor::SharedCursorHandle
  32. {
  33. public:
  34. explicit SharedCursorHandle (const MouseCursor::StandardCursorType type)
  35. : handle (createStandardMouseCursor (type)),
  36. refCount (1),
  37. standardType (type),
  38. isStandard (true)
  39. {
  40. }
  41. SharedCursorHandle (const Image& image, const Point<int>& hotSpot, const float scaleFactor)
  42. : handle (CustomMouseCursorInfo (image, hotSpot, scaleFactor).create()),
  43. refCount (1),
  44. standardType (MouseCursor::NormalCursor),
  45. isStandard (false)
  46. {
  47. }
  48. ~SharedCursorHandle()
  49. {
  50. deleteMouseCursor (handle, isStandard);
  51. }
  52. static SharedCursorHandle* createStandard (const MouseCursor::StandardCursorType type)
  53. {
  54. jassert (isPositiveAndBelow (type, MouseCursor::NumStandardCursorTypes));
  55. const SpinLock::ScopedLockType sl (lock);
  56. SharedCursorHandle*& c = getSharedCursor (type);
  57. if (c == nullptr)
  58. c = new SharedCursorHandle (type);
  59. else
  60. c->retain();
  61. return c;
  62. }
  63. bool isStandardType (MouseCursor::StandardCursorType type) const noexcept
  64. {
  65. return type == standardType && isStandard;
  66. }
  67. SharedCursorHandle* retain() noexcept
  68. {
  69. ++refCount;
  70. return this;
  71. }
  72. void release()
  73. {
  74. if (--refCount == 0)
  75. {
  76. if (isStandard)
  77. {
  78. const SpinLock::ScopedLockType sl (lock);
  79. getSharedCursor (standardType) = nullptr;
  80. }
  81. delete this;
  82. }
  83. }
  84. void* getHandle() const noexcept { return handle; }
  85. private:
  86. void* const handle;
  87. Atomic <int> refCount;
  88. const MouseCursor::StandardCursorType standardType;
  89. const bool isStandard;
  90. static SpinLock lock;
  91. static SharedCursorHandle*& getSharedCursor (const MouseCursor::StandardCursorType type)
  92. {
  93. static SharedCursorHandle* cursors [MouseCursor::NumStandardCursorTypes] = {};
  94. return cursors [type];
  95. }
  96. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedCursorHandle);
  97. };
  98. SpinLock MouseCursor::SharedCursorHandle::lock;
  99. //==============================================================================
  100. MouseCursor::MouseCursor()
  101. : cursorHandle (nullptr)
  102. {
  103. }
  104. MouseCursor::MouseCursor (const StandardCursorType type)
  105. : cursorHandle (type != MouseCursor::NormalCursor ? SharedCursorHandle::createStandard (type) : nullptr)
  106. {
  107. }
  108. MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY)
  109. : cursorHandle (new SharedCursorHandle (image, Point<int> (hotSpotX, hotSpotY), 1.0f))
  110. {
  111. }
  112. MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY, float scaleFactor)
  113. : cursorHandle (new SharedCursorHandle (image, Point<int> (hotSpotX, hotSpotY), scaleFactor))
  114. {
  115. }
  116. MouseCursor::MouseCursor (const MouseCursor& other)
  117. : cursorHandle (other.cursorHandle == nullptr ? nullptr : other.cursorHandle->retain())
  118. {
  119. }
  120. MouseCursor::~MouseCursor()
  121. {
  122. if (cursorHandle != nullptr)
  123. cursorHandle->release();
  124. }
  125. MouseCursor& MouseCursor::operator= (const MouseCursor& other)
  126. {
  127. if (other.cursorHandle != nullptr)
  128. other.cursorHandle->retain();
  129. if (cursorHandle != nullptr)
  130. cursorHandle->release();
  131. cursorHandle = other.cursorHandle;
  132. return *this;
  133. }
  134. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  135. MouseCursor::MouseCursor (MouseCursor&& other) noexcept
  136. : cursorHandle (other.cursorHandle)
  137. {
  138. other.cursorHandle = nullptr;
  139. }
  140. MouseCursor& MouseCursor::operator= (MouseCursor&& other) noexcept
  141. {
  142. std::swap (cursorHandle, other.cursorHandle);
  143. return *this;
  144. }
  145. #endif
  146. bool MouseCursor::operator== (const MouseCursor& other) const noexcept
  147. {
  148. return getHandle() == other.getHandle();
  149. }
  150. bool MouseCursor::operator== (StandardCursorType type) const noexcept
  151. {
  152. return cursorHandle != nullptr ? cursorHandle->isStandardType (type)
  153. : (type == NormalCursor);
  154. }
  155. bool MouseCursor::operator!= (const MouseCursor& other) const noexcept { return ! operator== (other); }
  156. bool MouseCursor::operator!= (StandardCursorType type) const noexcept { return ! operator== (type); }
  157. void* MouseCursor::getHandle() const noexcept
  158. {
  159. return cursorHandle != nullptr ? cursorHandle->getHandle() : nullptr;
  160. }
  161. void MouseCursor::showWaitCursor()
  162. {
  163. Desktop::getInstance().getMainMouseSource().showMouseCursor (MouseCursor::WaitCursor);
  164. }
  165. void MouseCursor::hideWaitCursor()
  166. {
  167. Desktop::getInstance().getMainMouseSource().revealCursor();
  168. }