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.

217 lines
6.3KB

  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. private:
  31. JUCE_DECLARE_NON_COPYABLE (CustomMouseCursorInfo);
  32. };
  33. class MouseCursor::SharedCursorHandle
  34. {
  35. public:
  36. explicit SharedCursorHandle (const MouseCursor::StandardCursorType type)
  37. : handle (createStandardMouseCursor (type)),
  38. refCount (1),
  39. standardType (type),
  40. isStandard (true)
  41. {
  42. }
  43. SharedCursorHandle (const Image& image, const Point<int>& hotSpot, const float scaleFactor)
  44. : handle (CustomMouseCursorInfo (image, hotSpot, scaleFactor).create()),
  45. refCount (1),
  46. standardType (MouseCursor::NormalCursor),
  47. isStandard (false)
  48. {
  49. }
  50. ~SharedCursorHandle()
  51. {
  52. deleteMouseCursor (handle, isStandard);
  53. }
  54. static SharedCursorHandle* createStandard (const MouseCursor::StandardCursorType type)
  55. {
  56. jassert (isPositiveAndBelow (type, MouseCursor::NumStandardCursorTypes));
  57. const SpinLock::ScopedLockType sl (lock);
  58. SharedCursorHandle*& c = getSharedCursor (type);
  59. if (c == nullptr)
  60. c = new SharedCursorHandle (type);
  61. else
  62. c->retain();
  63. return c;
  64. }
  65. bool isStandardType (MouseCursor::StandardCursorType type) const noexcept
  66. {
  67. return type == standardType && isStandard;
  68. }
  69. SharedCursorHandle* retain() noexcept
  70. {
  71. ++refCount;
  72. return this;
  73. }
  74. void release()
  75. {
  76. if (--refCount == 0)
  77. {
  78. if (isStandard)
  79. {
  80. const SpinLock::ScopedLockType sl (lock);
  81. getSharedCursor (standardType) = nullptr;
  82. }
  83. delete this;
  84. }
  85. }
  86. void* getHandle() const noexcept { return handle; }
  87. private:
  88. void* const handle;
  89. Atomic <int> refCount;
  90. const MouseCursor::StandardCursorType standardType;
  91. const bool isStandard;
  92. static SpinLock lock;
  93. static SharedCursorHandle*& getSharedCursor (const MouseCursor::StandardCursorType type)
  94. {
  95. static SharedCursorHandle* cursors [MouseCursor::NumStandardCursorTypes] = {};
  96. return cursors [type];
  97. }
  98. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedCursorHandle);
  99. };
  100. SpinLock MouseCursor::SharedCursorHandle::lock;
  101. //==============================================================================
  102. MouseCursor::MouseCursor()
  103. : cursorHandle (nullptr)
  104. {
  105. }
  106. MouseCursor::MouseCursor (const StandardCursorType type)
  107. : cursorHandle (type != MouseCursor::NormalCursor ? SharedCursorHandle::createStandard (type) : nullptr)
  108. {
  109. }
  110. MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY)
  111. : cursorHandle (new SharedCursorHandle (image, Point<int> (hotSpotX, hotSpotY), 1.0f))
  112. {
  113. }
  114. MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY, float scaleFactor)
  115. : cursorHandle (new SharedCursorHandle (image, Point<int> (hotSpotX, hotSpotY), scaleFactor))
  116. {
  117. }
  118. MouseCursor::MouseCursor (const MouseCursor& other)
  119. : cursorHandle (other.cursorHandle == nullptr ? nullptr : other.cursorHandle->retain())
  120. {
  121. }
  122. MouseCursor::~MouseCursor()
  123. {
  124. if (cursorHandle != nullptr)
  125. cursorHandle->release();
  126. }
  127. MouseCursor& MouseCursor::operator= (const MouseCursor& other)
  128. {
  129. if (other.cursorHandle != nullptr)
  130. other.cursorHandle->retain();
  131. if (cursorHandle != nullptr)
  132. cursorHandle->release();
  133. cursorHandle = other.cursorHandle;
  134. return *this;
  135. }
  136. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  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. #endif
  148. bool MouseCursor::operator== (const MouseCursor& other) const noexcept
  149. {
  150. return getHandle() == other.getHandle();
  151. }
  152. bool MouseCursor::operator== (StandardCursorType type) const noexcept
  153. {
  154. return cursorHandle != nullptr ? cursorHandle->isStandardType (type)
  155. : (type == NormalCursor);
  156. }
  157. bool MouseCursor::operator!= (const MouseCursor& other) const noexcept { return ! operator== (other); }
  158. bool MouseCursor::operator!= (StandardCursorType type) const noexcept { return ! operator== (type); }
  159. void* MouseCursor::getHandle() const noexcept
  160. {
  161. return cursorHandle != nullptr ? cursorHandle->getHandle() : nullptr;
  162. }
  163. void MouseCursor::showWaitCursor()
  164. {
  165. Desktop::getInstance().getMainMouseSource().showMouseCursor (MouseCursor::WaitCursor);
  166. }
  167. void MouseCursor::hideWaitCursor()
  168. {
  169. Desktop::getInstance().getMainMouseSource().revealCursor();
  170. }