Browse Source

Added an assertion if you try to create a MouseCursor with a hotspot that's outside the image bounds

tags/2021-05-28
jules 7 years ago
parent
commit
eece581e73
5 changed files with 27 additions and 34 deletions
  1. +13
    -20
      modules/juce_gui_basics/mouse/juce_MouseCursor.cpp
  2. +1
    -1
      modules/juce_gui_basics/mouse/juce_MouseCursor.h
  3. +3
    -3
      modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp
  4. +8
    -8
      modules/juce_gui_basics/native/juce_mac_MouseCursor.mm
  5. +2
    -2
      modules/juce_gui_basics/native/juce_win32_Windowing.cpp

+ 13
- 20
modules/juce_gui_basics/mouse/juce_MouseCursor.cpp View File

@@ -29,11 +29,7 @@ namespace juce
struct CustomMouseCursorInfo struct CustomMouseCursorInfo
{ {
CustomMouseCursorInfo (const Image& im, int hsX, int hsY) noexcept
: image (im), hotspot (hsX, hsY), scaleFactor (1.0f)
{}
CustomMouseCursorInfo (const Image& im, Point<int> hs, float scale) noexcept
CustomMouseCursorInfo (const Image& im, Point<int> hs, float scale = 1.0f) noexcept
: image (im), hotspot (hs), scaleFactor (scale) : image (im), hotspot (hs), scaleFactor (scale)
{} {}
@@ -41,9 +37,8 @@ struct CustomMouseCursorInfo
Image image; Image image;
const Point<int> hotspot; const Point<int> hotspot;
float scaleFactor;
const float scaleFactor;
private:
JUCE_DECLARE_NON_COPYABLE (CustomMouseCursorInfo) JUCE_DECLARE_NON_COPYABLE (CustomMouseCursorInfo)
}; };
@@ -52,18 +47,18 @@ class MouseCursor::SharedCursorHandle
public: public:
explicit SharedCursorHandle (const MouseCursor::StandardCursorType type) explicit SharedCursorHandle (const MouseCursor::StandardCursorType type)
: handle (createStandardMouseCursor (type)), : handle (createStandardMouseCursor (type)),
refCount (1),
standardType (type), standardType (type),
isStandard (true) isStandard (true)
{ {
} }
SharedCursorHandle (const Image& image, Point<int> hotSpot, const float scaleFactor)
SharedCursorHandle (const Image& image, Point<int> hotSpot, float scaleFactor)
: handle (CustomMouseCursorInfo (image, hotSpot, scaleFactor).create()), : handle (CustomMouseCursorInfo (image, hotSpot, scaleFactor).create()),
refCount (1),
standardType (MouseCursor::NormalCursor), standardType (MouseCursor::NormalCursor),
isStandard (false) isStandard (false)
{ {
// your hotspot needs to be within the bounds of the image!
jassert (image.getBounds().contains (hotSpot));
} }
~SharedCursorHandle() ~SharedCursorHandle()
@@ -76,8 +71,7 @@ public:
jassert (isPositiveAndBelow (type, MouseCursor::NumStandardCursorTypes)); jassert (isPositiveAndBelow (type, MouseCursor::NumStandardCursorTypes));
const SpinLock::ScopedLockType sl (lock); const SpinLock::ScopedLockType sl (lock);
SharedCursorHandle*& c = getSharedCursor (type);
auto& c = getSharedCursor (type);
if (c == nullptr) if (c == nullptr)
c = new SharedCursorHandle (type); c = new SharedCursorHandle (type);
@@ -116,15 +110,15 @@ public:
private: private:
void* const handle; void* const handle;
Atomic <int> refCount;
Atomic<int> refCount { 1 };
const MouseCursor::StandardCursorType standardType; const MouseCursor::StandardCursorType standardType;
const bool isStandard; const bool isStandard;
static SpinLock lock; static SpinLock lock;
static SharedCursorHandle*& getSharedCursor (const MouseCursor::StandardCursorType type) static SharedCursorHandle*& getSharedCursor (const MouseCursor::StandardCursorType type)
{ {
static SharedCursorHandle* cursors [MouseCursor::NumStandardCursorTypes] = {};
return cursors [type];
static SharedCursorHandle* cursors[MouseCursor::NumStandardCursorTypes] = {};
return cursors[type];
} }
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedCursorHandle) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SharedCursorHandle)
@@ -134,7 +128,6 @@ SpinLock MouseCursor::SharedCursorHandle::lock;
//============================================================================== //==============================================================================
MouseCursor::MouseCursor() noexcept MouseCursor::MouseCursor() noexcept
: cursorHandle (nullptr)
{ {
} }
@@ -143,13 +136,13 @@ MouseCursor::MouseCursor (const StandardCursorType type)
{ {
} }
MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY)
: cursorHandle (new SharedCursorHandle (image, Point<int> (hotSpotX, hotSpotY), 1.0f))
MouseCursor::MouseCursor (const Image& image, int hotSpotX, int hotSpotY)
: MouseCursor (image, hotSpotX, hotSpotY, 1.0f)
{ {
} }
MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY, float scaleFactor)
: cursorHandle (new SharedCursorHandle (image, Point<int> (hotSpotX, hotSpotY), scaleFactor))
MouseCursor::MouseCursor (const Image& image, int hotSpotX, int hotSpotY, float scaleFactor)
: cursorHandle (new SharedCursorHandle (image, { hotSpotX, hotSpotY }, scaleFactor))
{ {
} }


+ 1
- 1
modules/juce_gui_basics/mouse/juce_MouseCursor.h View File

@@ -166,7 +166,7 @@ private:
//============================================================================== //==============================================================================
class SharedCursorHandle; class SharedCursorHandle;
friend class SharedCursorHandle; friend class SharedCursorHandle;
SharedCursorHandle* cursorHandle;
SharedCursorHandle* cursorHandle = nullptr;
friend class MouseInputSourceInternal; friend class MouseInputSourceInternal;
void showInWindow (ComponentPeer* window) const; void showInWindow (ComponentPeer* window) const;


+ 3
- 3
modules/juce_gui_basics/native/juce_linux_X11_Windowing.cpp View File

@@ -1468,7 +1468,7 @@ static void* createDraggingHandCursor()
132,117,151,116,132,146,248,60,209,138,98,22,203,114,34,236,37,52,77,217, 247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 }; 132,117,151,116,132,146,248,60,209,138,98,22,203,114,34,236,37,52,77,217, 247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 };
const int dragHandDataSize = 99; const int dragHandDataSize = 99;
return CustomMouseCursorInfo (ImageFileFormat::loadFrom (dragHandData, dragHandDataSize), 8, 7).create();
return CustomMouseCursorInfo (ImageFileFormat::loadFrom (dragHandData, dragHandDataSize), { 8, 7 }).create();
} }
//============================================================================== //==============================================================================
@@ -4269,7 +4269,7 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty
{ {
case NormalCursor: case NormalCursor:
case ParentCursor: return None; // Use parent cursor case ParentCursor: return None; // Use parent cursor
case NoCursor: return CustomMouseCursorInfo (Image (Image::ARGB, 16, 16, true), 0, 0).create();
case NoCursor: return CustomMouseCursorInfo (Image (Image::ARGB, 16, 16, true), {}).create();
case WaitCursor: shape = XC_watch; break; case WaitCursor: shape = XC_watch; break;
case IBeamCursor: shape = XC_xterm; break; case IBeamCursor: shape = XC_xterm; break;
@@ -4296,7 +4296,7 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty
252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 }; 252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 };
const int copyCursorSize = 119; const int copyCursorSize = 119;
return CustomMouseCursorInfo (ImageFileFormat::loadFrom (copyCursorData, copyCursorSize), 1, 3).create();
return CustomMouseCursorInfo (ImageFileFormat::loadFrom (copyCursorData, copyCursorSize), { 1, 3 }).create();
} }
default: default:


+ 8
- 8
modules/juce_gui_basics/native/juce_mac_MouseCursor.mm View File

@@ -38,7 +38,7 @@ namespace MouseCursorHelpers
JUCE_AUTORELEASEPOOL JUCE_AUTORELEASEPOOL
{ {
NSImage* im = [[NSImage alloc] init]; NSImage* im = [[NSImage alloc] init];
const NSSize requiredSize = NSMakeSize (image.getWidth() / scaleFactor, image.getHeight() / scaleFactor);
auto requiredSize = NSMakeSize (image.getWidth() / scaleFactor, image.getHeight() / scaleFactor);
[im setSize: requiredSize]; [im setSize: requiredSize];
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
@@ -66,9 +66,9 @@ namespace MouseCursorHelpers
{ {
JUCE_AUTORELEASEPOOL JUCE_AUTORELEASEPOOL
{ {
const String cursorPath (String ("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/"
"HIServices.framework/Versions/A/Resources/cursors/")
+ filename);
auto cursorPath = String ("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/"
"HIServices.framework/Versions/A/Resources/cursors/")
+ filename;
NSImage* originalImage = [[NSImage alloc] initByReferencingFile: juceStringToNS (cursorPath + "/cursor.pdf")]; NSImage* originalImage = [[NSImage alloc] initByReferencingFile: juceStringToNS (cursorPath + "/cursor.pdf")];
NSSize originalSize = [originalImage size]; NSSize originalSize = [originalImage size];
@@ -100,8 +100,8 @@ namespace MouseCursorHelpers
NSDictionary* info = [NSDictionary dictionaryWithContentsOfFile: juceStringToNS (cursorPath + "/info.plist")]; NSDictionary* info = [NSDictionary dictionaryWithContentsOfFile: juceStringToNS (cursorPath + "/info.plist")];
const float hotspotX = (float) [[info valueForKey: nsStringLiteral ("hotx")] doubleValue];
const float hotspotY = (float) [[info valueForKey: nsStringLiteral ("hoty")] doubleValue];
auto hotspotX = (float) [[info valueForKey: nsStringLiteral ("hotx")] doubleValue];
auto hotspotY = (float) [[info valueForKey: nsStringLiteral ("hoty")] doubleValue];
return fromNSImage (resultImage, NSMakePoint (hotspotX, hotspotY)); return fromNSImage (resultImage, NSMakePoint (hotspotX, hotspotY));
} }
@@ -124,7 +124,7 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty
{ {
case NormalCursor: case NormalCursor:
case ParentCursor: c = [NSCursor arrowCursor]; break; case ParentCursor: c = [NSCursor arrowCursor]; break;
case NoCursor: return CustomMouseCursorInfo (Image (Image::ARGB, 8, 8, true), 0, 0).create();
case NoCursor: return CustomMouseCursorInfo (Image (Image::ARGB, 8, 8, true), {}).create();
case DraggingHandCursor: c = [NSCursor openHandCursor]; break; case DraggingHandCursor: c = [NSCursor openHandCursor]; break;
case WaitCursor: c = [NSCursor arrowCursor]; break; // avoid this on the mac, let the OS provide the beachball case WaitCursor: c = [NSCursor arrowCursor]; break; // avoid this on the mac, let the OS provide the beachball
case IBeamCursor: c = [NSCursor IBeamCursor]; break; case IBeamCursor: c = [NSCursor IBeamCursor]; break;
@@ -193,7 +193,7 @@ void MouseCursor::showInAllWindows() const
void MouseCursor::showInWindow (ComponentPeer*) const void MouseCursor::showInWindow (ComponentPeer*) const
{ {
NSCursor* c = (NSCursor*) getHandle();
auto c = (NSCursor*) getHandle();
if (c == nil) if (c == nil)
c = [NSCursor arrowCursor]; c = [NSCursor arrowCursor];


+ 2
- 2
modules/juce_gui_basics/native/juce_win32_Windowing.cpp View File

@@ -4125,7 +4125,7 @@ void* MouseCursor::createStandardMouseCursor (const MouseCursor::StandardCursorT
16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39,132,117,151,116,132,146,248,60,209,138, 16,0,0,2,52,148,47,0,200,185,16,130,90,12,74,139,107,84,123,39,132,117,151,116,132,146,248,60,209,138,
98,22,203,114,34,236,37,52,77,217,247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 }; 98,22,203,114,34,236,37,52,77,217,247,154,191,119,110,240,193,128,193,95,163,56,60,234,98,135,2,0,59 };
dragHandCursor = CustomMouseCursorInfo (ImageFileFormat::loadFrom (dragHandData, sizeof (dragHandData)), 8, 7).create();
dragHandCursor = CustomMouseCursorInfo (ImageFileFormat::loadFrom (dragHandData, sizeof (dragHandData)), { 8, 7 }).create();
} }
return dragHandCursor; return dragHandCursor;
@@ -4143,7 +4143,7 @@ void* MouseCursor::createStandardMouseCursor (const MouseCursor::StandardCursorT
252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 }; 252,114,147,74,83,5,50,68,147,208,217,16,71,149,252,124,5,0,59,0,0 };
const int copyCursorSize = 119; const int copyCursorSize = 119;
copyCursor = CustomMouseCursorInfo (ImageFileFormat::loadFrom (copyCursorData, copyCursorSize), 1, 3).create();
copyCursor = CustomMouseCursorInfo (ImageFileFormat::loadFrom (copyCursorData, copyCursorSize), { 1, 3 }).create();
} }
return copyCursor; return copyCursor;


Loading…
Cancel
Save