Audio plugin host https://kx.studio/carla
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.

juce_MouseCursor.cpp 6.1KB

9 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. struct CustomMouseCursorInfo
  18. {
  19. CustomMouseCursorInfo (const Image& im, int hsX, int hsY) noexcept
  20. : image (im), hotspot (hsX, hsY), scaleFactor (1.0f)
  21. {}
  22. CustomMouseCursorInfo (const Image& im, Point<int> hs, float scale) noexcept
  23. : image (im), hotspot (hs), scaleFactor (scale)
  24. {}
  25. void* create() const;
  26. Image image;
  27. const Point<int> hotspot;
  28. float scaleFactor;
  29. private:
  30. JUCE_DECLARE_NON_COPYABLE (CustomMouseCursorInfo)
  31. };
  32. class MouseCursor::SharedCursorHandle
  33. {
  34. public:
  35. explicit SharedCursorHandle (const MouseCursor::StandardCursorType type)
  36. : handle (createStandardMouseCursor (type)),
  37. refCount (1),
  38. standardType (type),
  39. isStandard (true)
  40. {
  41. }
  42. SharedCursorHandle (const Image& image, Point<int> hotSpot, const float scaleFactor)
  43. : handle (CustomMouseCursorInfo (image, hotSpot, scaleFactor).create()),
  44. refCount (1),
  45. standardType (MouseCursor::NormalCursor),
  46. isStandard (false)
  47. {
  48. }
  49. ~SharedCursorHandle()
  50. {
  51. deleteMouseCursor (handle, isStandard);
  52. }
  53. static SharedCursorHandle* createStandard (const MouseCursor::StandardCursorType type)
  54. {
  55. jassert (isPositiveAndBelow (type, MouseCursor::NumStandardCursorTypes));
  56. const SpinLock::ScopedLockType sl (lock);
  57. SharedCursorHandle*& c = getSharedCursor (type);
  58. if (c == nullptr)
  59. c = new SharedCursorHandle (type);
  60. else
  61. c->retain();
  62. return c;
  63. }
  64. bool isStandardType (MouseCursor::StandardCursorType type) const noexcept
  65. {
  66. return type == standardType && isStandard;
  67. }
  68. SharedCursorHandle* retain() noexcept
  69. {
  70. ++refCount;
  71. return this;
  72. }
  73. void release()
  74. {
  75. if (--refCount == 0)
  76. {
  77. if (isStandard)
  78. {
  79. const SpinLock::ScopedLockType sl (lock);
  80. getSharedCursor (standardType) = nullptr;
  81. }
  82. delete this;
  83. }
  84. }
  85. void* getHandle() const noexcept { return handle; }
  86. private:
  87. void* const handle;
  88. Atomic <int> refCount;
  89. const MouseCursor::StandardCursorType standardType;
  90. const bool isStandard;
  91. static SpinLock lock;
  92. static SharedCursorHandle*& getSharedCursor (const MouseCursor::StandardCursorType type)
  93. {
  94. static SharedCursorHandle* cursors [MouseCursor::NumStandardCursorTypes] = {};
  95. return cursors [type];
  96. }
  97. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedCursorHandle)
  98. };
  99. SpinLock MouseCursor::SharedCursorHandle::lock;
  100. //==============================================================================
  101. MouseCursor::MouseCursor() noexcept
  102. : cursorHandle (nullptr)
  103. {
  104. }
  105. MouseCursor::MouseCursor (const StandardCursorType type)
  106. : cursorHandle (type != MouseCursor::NormalCursor ? SharedCursorHandle::createStandard (type) : nullptr)
  107. {
  108. }
  109. MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY)
  110. : cursorHandle (new SharedCursorHandle (image, Point<int> (hotSpotX, hotSpotY), 1.0f))
  111. {
  112. }
  113. MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY, float scaleFactor)
  114. : cursorHandle (new SharedCursorHandle (image, Point<int> (hotSpotX, hotSpotY), scaleFactor))
  115. {
  116. }
  117. MouseCursor::MouseCursor (const MouseCursor& other)
  118. : cursorHandle (other.cursorHandle == nullptr ? nullptr : other.cursorHandle->retain())
  119. {
  120. }
  121. MouseCursor::~MouseCursor()
  122. {
  123. if (cursorHandle != nullptr)
  124. cursorHandle->release();
  125. }
  126. MouseCursor& MouseCursor::operator= (const MouseCursor& other)
  127. {
  128. if (other.cursorHandle != nullptr)
  129. other.cursorHandle->retain();
  130. if (cursorHandle != nullptr)
  131. cursorHandle->release();
  132. cursorHandle = other.cursorHandle;
  133. return *this;
  134. }
  135. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  136. MouseCursor::MouseCursor (MouseCursor&& other) noexcept
  137. : cursorHandle (other.cursorHandle)
  138. {
  139. other.cursorHandle = nullptr;
  140. }
  141. MouseCursor& MouseCursor::operator= (MouseCursor&& other) noexcept
  142. {
  143. std::swap (cursorHandle, other.cursorHandle);
  144. return *this;
  145. }
  146. #endif
  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. }