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.

192 lines
5.6KB

  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. class MouseCursor::SharedCursorHandle
  19. {
  20. public:
  21. explicit SharedCursorHandle (const MouseCursor::StandardCursorType type)
  22. : handle (createStandardMouseCursor (type)),
  23. refCount (1),
  24. standardType (type),
  25. isStandard (true)
  26. {
  27. }
  28. SharedCursorHandle (const Image& image, const int hotSpotX, const int hotSpotY)
  29. : handle (createMouseCursorFromImage (image, hotSpotX, hotSpotY)),
  30. refCount (1),
  31. standardType (MouseCursor::NormalCursor),
  32. isStandard (false)
  33. {
  34. }
  35. ~SharedCursorHandle()
  36. {
  37. deleteMouseCursor (handle, isStandard);
  38. }
  39. static SharedCursorHandle* createStandard (const MouseCursor::StandardCursorType type)
  40. {
  41. jassert (isPositiveAndBelow (type, MouseCursor::NumStandardCursorTypes));
  42. const SpinLock::ScopedLockType sl (lock);
  43. SharedCursorHandle*& c = getSharedCursor (type);
  44. if (c == nullptr)
  45. c = new SharedCursorHandle (type);
  46. else
  47. c->retain();
  48. return c;
  49. }
  50. bool isStandardType (MouseCursor::StandardCursorType type) const noexcept
  51. {
  52. return type == standardType && isStandard;
  53. }
  54. SharedCursorHandle* retain() noexcept
  55. {
  56. ++refCount;
  57. return this;
  58. }
  59. void release()
  60. {
  61. if (--refCount == 0)
  62. {
  63. if (isStandard)
  64. {
  65. const SpinLock::ScopedLockType sl (lock);
  66. getSharedCursor (standardType) = nullptr;
  67. }
  68. delete this;
  69. }
  70. }
  71. void* getHandle() const noexcept { return handle; }
  72. private:
  73. void* const handle;
  74. Atomic <int> refCount;
  75. const MouseCursor::StandardCursorType standardType;
  76. const bool isStandard;
  77. static SpinLock lock;
  78. static SharedCursorHandle*& getSharedCursor (const MouseCursor::StandardCursorType type)
  79. {
  80. static SharedCursorHandle* cursors [MouseCursor::NumStandardCursorTypes] = {};
  81. return cursors [type];
  82. }
  83. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedCursorHandle);
  84. };
  85. SpinLock MouseCursor::SharedCursorHandle::lock;
  86. //==============================================================================
  87. MouseCursor::MouseCursor()
  88. : cursorHandle (nullptr)
  89. {
  90. }
  91. MouseCursor::MouseCursor (const StandardCursorType type)
  92. : cursorHandle (type != MouseCursor::NormalCursor ? SharedCursorHandle::createStandard (type) : nullptr)
  93. {
  94. }
  95. MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY)
  96. : cursorHandle (new SharedCursorHandle (image, hotSpotX, hotSpotY))
  97. {
  98. }
  99. MouseCursor::MouseCursor (const MouseCursor& other)
  100. : cursorHandle (other.cursorHandle == nullptr ? nullptr : other.cursorHandle->retain())
  101. {
  102. }
  103. MouseCursor::~MouseCursor()
  104. {
  105. if (cursorHandle != nullptr)
  106. cursorHandle->release();
  107. }
  108. MouseCursor& MouseCursor::operator= (const MouseCursor& other)
  109. {
  110. if (other.cursorHandle != nullptr)
  111. other.cursorHandle->retain();
  112. if (cursorHandle != nullptr)
  113. cursorHandle->release();
  114. cursorHandle = other.cursorHandle;
  115. return *this;
  116. }
  117. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  118. MouseCursor::MouseCursor (MouseCursor&& other) noexcept
  119. : cursorHandle (other.cursorHandle)
  120. {
  121. other.cursorHandle = nullptr;
  122. }
  123. MouseCursor& MouseCursor::operator= (MouseCursor&& other) noexcept
  124. {
  125. std::swap (cursorHandle, other.cursorHandle);
  126. return *this;
  127. }
  128. #endif
  129. bool MouseCursor::operator== (const MouseCursor& other) const noexcept
  130. {
  131. return getHandle() == other.getHandle();
  132. }
  133. bool MouseCursor::operator== (StandardCursorType type) const noexcept
  134. {
  135. return cursorHandle != nullptr ? cursorHandle->isStandardType (type)
  136. : (type == NormalCursor);
  137. }
  138. bool MouseCursor::operator!= (const MouseCursor& other) const noexcept { return ! operator== (other); }
  139. bool MouseCursor::operator!= (StandardCursorType type) const noexcept { return ! operator== (type); }
  140. void* MouseCursor::getHandle() const noexcept
  141. {
  142. return cursorHandle != nullptr ? cursorHandle->getHandle() : nullptr;
  143. }
  144. void MouseCursor::showWaitCursor()
  145. {
  146. Desktop::getInstance().getMainMouseSource().showMouseCursor (MouseCursor::WaitCursor);
  147. }
  148. void MouseCursor::hideWaitCursor()
  149. {
  150. Desktop::getInstance().getMainMouseSource().revealCursor();
  151. }