From d5dc5b2ba97dbcd42d8dff33bbd5f7891548bd99 Mon Sep 17 00:00:00 2001 From: jules Date: Fri, 21 Sep 2012 15:59:12 +0100 Subject: [PATCH] MouseCursor refactoring. --- .../mouse/juce_MouseCursor.cpp | 28 +++++++++++++-- .../juce_gui_basics/mouse/juce_MouseCursor.h | 26 ++++++++++---- .../native/juce_android_Windowing.cpp | 2 +- .../native/juce_linux_Windowing.cpp | 10 +++--- .../native/juce_mac_MouseCursor.mm | 34 ++++++++----------- .../native/juce_win32_Windowing.cpp | 6 ++-- 6 files changed, 70 insertions(+), 36 deletions(-) diff --git a/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp b/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp index 335d8e5849..8cfab6042a 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp +++ b/modules/juce_gui_basics/mouse/juce_MouseCursor.cpp @@ -23,6 +23,23 @@ ============================================================================== */ +struct CustomMouseCursorInfo +{ + CustomMouseCursorInfo (const Image& im, int hsX, int hsY) noexcept + : image (im), hotspot (hsX, hsY), scaleFactor (1.0f) + {} + + CustomMouseCursorInfo (const Image& im, const Point& hs, float scale) noexcept + : image (im), hotspot (hs), scaleFactor (scale) + {} + + void* create() const; + + Image image; + const Point hotspot; + float scaleFactor; +}; + class MouseCursor::SharedCursorHandle { public: @@ -34,8 +51,8 @@ public: { } - SharedCursorHandle (const Image& image, const int hotSpotX, const int hotSpotY) - : handle (createMouseCursorFromImage (image, hotSpotX, hotSpotY)), + SharedCursorHandle (const Image& image, const Point& hotSpot, const float scaleFactor) + : handle (CustomMouseCursorInfo (image, hotSpot, scaleFactor).create()), refCount (1), standardType (MouseCursor::NormalCursor), isStandard (false) @@ -120,7 +137,12 @@ MouseCursor::MouseCursor (const StandardCursorType type) } MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY) - : cursorHandle (new SharedCursorHandle (image, hotSpotX, hotSpotY)) + : cursorHandle (new SharedCursorHandle (image, Point (hotSpotX, hotSpotY), 1.0f)) +{ +} + +MouseCursor::MouseCursor (const Image& image, const int hotSpotX, const int hotSpotY, float scaleFactor) + : cursorHandle (new SharedCursorHandle (image, Point (hotSpotX, hotSpotY), scaleFactor)) { } diff --git a/modules/juce_gui_basics/mouse/juce_MouseCursor.h b/modules/juce_gui_basics/mouse/juce_MouseCursor.h index 04995eb072..58588afb0e 100644 --- a/modules/juce_gui_basics/mouse/juce_MouseCursor.h +++ b/modules/juce_gui_basics/mouse/juce_MouseCursor.h @@ -93,19 +93,32 @@ public: */ MouseCursor (const Image& image, int hotSpotX, int hotSpotY); + /** Creates a custom cursor from an image. + + @param image the image to use for the cursor - if this is bigger than the + system can manage, it might get scaled down first, and might + also have to be turned to black-and-white if it can't do colour + cursors. + @param hotSpotX the x position of the cursor's hotspot within the image + @param hotSpotY the y position of the cursor's hotspot within the image + @param dpiFactor the factor by which this image is larger than the target + screen size of the cursor. + */ + MouseCursor (const Image& image, int hotSpotX, int hotSpotY, float scaleFactor); + //============================================================================== /** Creates a copy of another cursor object. */ - MouseCursor (const MouseCursor& other); + MouseCursor (const MouseCursor&); /** Copies this cursor from another object. */ - MouseCursor& operator= (const MouseCursor& other); + MouseCursor& operator= (const MouseCursor&); /** Destructor. */ ~MouseCursor(); #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS - MouseCursor (MouseCursor&& other) noexcept; - MouseCursor& operator= (MouseCursor&& other) noexcept; + MouseCursor (MouseCursor&&) noexcept; + MouseCursor& operator= (MouseCursor&&) noexcept; #endif /** Checks whether two mouse cursors are the same. @@ -114,7 +127,7 @@ public: recognised as the same, only MouseCursor objects that have been copied from the same object. */ - bool operator== (const MouseCursor& other) const noexcept; + bool operator== (const MouseCursor&) const noexcept; /** Checks whether two mouse cursors are the same. @@ -122,7 +135,7 @@ public: recognised as the same, only MouseCursor objects that have been copied from the same object. */ - bool operator!= (const MouseCursor& other) const noexcept; + bool operator!= (const MouseCursor&) const noexcept; /** Checks whether this cursor is of the standard type mentioned. */ bool operator== (StandardCursorType type) const noexcept; @@ -165,7 +178,6 @@ private: void showInAllWindows() const; void* getHandle() const noexcept; - static void* createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY); static void* createStandardMouseCursor (MouseCursor::StandardCursorType type); static void deleteMouseCursor (void* cursorHandle, bool isStandard); diff --git a/modules/juce_gui_basics/native/juce_android_Windowing.cpp b/modules/juce_gui_basics/native/juce_android_Windowing.cpp index 43a40bd4d3..be6b35fb0c 100644 --- a/modules/juce_gui_basics/native/juce_android_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_android_Windowing.cpp @@ -715,7 +715,7 @@ Image juce_createIconForFile (const File& file) } //============================================================================== -void* MouseCursor::createMouseCursorFromImage (const Image&, int, int) { return nullptr; } +void* CustomMouseCursorInfo::create() const { return nullptr; } void* MouseCursor::createStandardMouseCursor (const MouseCursor::StandardCursorType) { return nullptr; } void MouseCursor::deleteMouseCursor (void* const /*cursorHandle*/, const bool /*isStandard*/) {} diff --git a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp index 23464dd406..8c511b1dd0 100644 --- a/modules/juce_gui_basics/native/juce_linux_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_linux_Windowing.cpp @@ -2800,11 +2800,13 @@ bool Desktop::isScreenSaverEnabled() } //============================================================================== -void* MouseCursor::createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) +void* CustomMouseCursorInfo::create() const { ScopedXLock xlock; const unsigned int imageW = image.getWidth(); const unsigned int imageH = image.getHeight(); + int hotspotX = hotspot.x; + int hotspotY = hotspot.y; #if JUCE_USE_XCURSOR { @@ -2935,7 +2937,7 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty { case NormalCursor: case ParentCursor: return None; // Use parent cursor - case NoCursor: return createMouseCursorFromImage (Image (Image::ARGB, 16, 16, true), 0, 0); + case NoCursor: return CustomMouseCursorInfo (Image (Image::ARGB, 16, 16, true), 0, 0).create(); case WaitCursor: shape = XC_watch; break; case IBeamCursor: shape = XC_xterm; break; @@ -2960,7 +2962,7 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty 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; - return createMouseCursorFromImage (ImageFileFormat::loadFrom (dragHandData, dragHandDataSize), 8, 7); + return CustomMouseCursorInfo (ImageFileFormat::loadFrom (dragHandData, dragHandDataSize), 8, 7).create(); } case CopyingCursor: @@ -2971,7 +2973,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 }; const int copyCursorSize = 119; - return createMouseCursorFromImage (ImageFileFormat::loadFrom (copyCursorData, copyCursorSize), 1, 3); + return CustomMouseCursorInfo (ImageFileFormat::loadFrom (copyCursorData, copyCursorSize), 1, 3).create(); } default: diff --git a/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm b/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm index 2c31c21f4e..526520cb94 100644 --- a/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm +++ b/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm @@ -41,7 +41,7 @@ namespace MouseCursorHelpers CGColorSpaceRelease (colourSpace); CGContextRef cg = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; - CGContextDrawImage (cg, CGRectMake (0, 0, image.getWidth(), image.getHeight()), imageRef); + CGContextDrawImage (cg, convertToCGRect (image.getBounds()), imageRef); CGImageRelease (imageRef); [im unlockFocus]; @@ -49,15 +49,6 @@ namespace MouseCursorHelpers return im; } - static void* createFromImage (const Image& image, float hotspotX, float hotspotY) - { - NSImage* im = createNSImage (image); - NSCursor* c = [[NSCursor alloc] initWithImage: im - hotSpot: NSMakePoint (hotspotX, hotspotY)]; - [im release]; - return c; - } - static void* fromWebKitFile (const char* filename, float hx, float hy) { FileInputStream fileStream (String ("/System/Library/Frameworks/WebKit.framework/Frameworks/WebCore.framework/Resources/") + filename); @@ -67,16 +58,21 @@ namespace MouseCursorHelpers Image im (pngFormat.decodeImage (buf)); if (im.isValid()) - return createFromImage (im, hx * im.getWidth(), hy * im.getHeight()); + return CustomMouseCursorInfo (im, (int) (hx * im.getWidth()), + (int) (hy * im.getHeight())).create(); jassertfalse; return nullptr; } } -void* MouseCursor::createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) +void* CustomMouseCursorInfo::create() const { - return MouseCursorHelpers::createFromImage (image, (float) hotspotX, (float) hotspotY); + NSImage* im = MouseCursorHelpers::createNSImage (image); + NSCursor* c = [[NSCursor alloc] initWithImage: im + hotSpot: NSMakePoint (hotspot.x, hotspot.y)]; + [im release]; + return c; } void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType type) @@ -88,7 +84,7 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty { case NormalCursor: case ParentCursor: c = [NSCursor arrowCursor]; break; - case NoCursor: return createMouseCursorFromImage (Image (Image::ARGB, 8, 8, true), 0, 0); + case NoCursor: return CustomMouseCursorInfo (Image (Image::ARGB, 8, 8, true), 0, 0).create(); case DraggingHandCursor: c = [NSCursor openHandCursor]; break; case WaitCursor: c = [NSCursor arrowCursor]; break; // avoid this on the mac, let the OS provide the beachball case IBeamCursor: c = [NSCursor IBeamCursor]; break; @@ -146,10 +142,10 @@ void MouseCursor::showInWindow (ComponentPeer*) const #else -void* MouseCursor::createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) { return nullptr; } -void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType type) { return nullptr; } -void MouseCursor::deleteMouseCursor (void* const cursorHandle, const bool isStandard) {} -void MouseCursor::showInAllWindows() const {} -void MouseCursor::showInWindow (ComponentPeer*) const {} +void* CustomMouseCursorInfo::create() const { return nullptr; } +void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType type) { return nullptr; } +void MouseCursor::deleteMouseCursor (void* const cursorHandle, const bool isStandard) {} +void MouseCursor::showInAllWindows() const {} +void MouseCursor::showInWindow (ComponentPeer*) const {} #endif diff --git a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index 84fe04aeea..a6e2472dc3 100644 --- a/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -3129,12 +3129,14 @@ Image juce_createIconForFile (const File& file) } //============================================================================== -void* MouseCursor::createMouseCursorFromImage (const Image& image, int hotspotX, int hotspotY) +void* CustomMouseCursorInfo::create() const { const int maxW = GetSystemMetrics (SM_CXCURSOR); const int maxH = GetSystemMetrics (SM_CYCURSOR); Image im (image); + int hotspotX = hotspot.x; + int hotspotY = hotspot.y; if (im.getWidth() > maxW || im.getHeight() > maxH) { @@ -3200,7 +3202,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, 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 = createMouseCursorFromImage (ImageFileFormat::loadFrom (dragHandData, sizeof (dragHandData)), 8, 7); + dragHandCursor = CustomMouseCursorInfo (ImageFileFormat::loadFrom (dragHandData, sizeof (dragHandData)), 8, 7).create(); } return dragHandCursor;