зеркало из https://github.com/mozilla/pjs.git
Implement CSS cursor support for Mac OS X. b=286304 r=josh
This commit is contained in:
Родитель
3ca6f879df
Коммит
10f77c8a5c
|
@ -977,8 +977,7 @@ NS_IMETHODIMP nsChildView::SetCursor(nsCursor aCursor)
|
|||
return NS_OK; // Don't change the cursor during dragging.
|
||||
|
||||
nsBaseWidget::SetCursor(aCursor);
|
||||
[[nsCursorManager sharedInstance] setCursor: aCursor];
|
||||
return NS_OK;
|
||||
return [[nsCursorManager sharedInstance] setCursor:aCursor];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
@ -987,7 +986,12 @@ NS_IMETHODIMP nsChildView::SetCursor(nsCursor aCursor)
|
|||
NS_IMETHODIMP nsChildView::SetCursor(imgIContainer* aCursor,
|
||||
PRUint32 aHotspotX, PRUint32 aHotspotY)
|
||||
{
|
||||
return nsBaseWidget::SetCursor(aCursor, aHotspotX, aHotspotY);
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
nsBaseWidget::SetCursor(aCursor, aHotspotX, aHotspotY);
|
||||
return [[nsCursorManager sharedInstance] setCursorWithImage:aCursor hotSpotX:aHotspotX hotSpotY:aHotspotY];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
#include "nsRect.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "imgIContainer.h"
|
||||
|
||||
class nsIWidget;
|
||||
|
||||
|
@ -130,6 +131,37 @@ class nsCocoaUtils
|
|||
|
||||
static void PrepareForNativeAppModalDialog();
|
||||
static void CleanUpAfterNativeAppModalDialog();
|
||||
|
||||
// 3 utility functions to go from a frame of imgIContainer to CGImage and then to NSImage
|
||||
// Convert imgIContainer -> CGImageRef, caller owns result
|
||||
|
||||
/** Creates a <code>CGImageRef</code> from a frame contained in an <code>imgIContainer</code>.
|
||||
Copies the pixel data from the indicated frame of the <code>imgIContainer</code> into a new <code>CGImageRef</code>.
|
||||
The caller owns the <code>CGImageRef</code>.
|
||||
@param aImage the image to extract a frame from
|
||||
@param aWhichFrame the frame to extract (see imgIContainer FRAME_*)
|
||||
@param aResult the resulting CGImageRef
|
||||
@return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
|
||||
*/
|
||||
static nsresult CreateCGImageFromImageContainer(imgIContainer *aImage, PRUint32 aWhichFrame, CGImageRef *aResult);
|
||||
|
||||
/** Creates a Cocoa <code>NSImage</code> from a <code>CGImageRef</code>.
|
||||
Copies the pixel data from the <code>CGImageRef</code> into a new <code>NSImage</code>.
|
||||
The caller owns the <code>NSImage</code>.
|
||||
@param aInputImage the image to convert
|
||||
@param aResult the resulting NSImage
|
||||
@return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
|
||||
*/
|
||||
static nsresult CreateNSImageFromCGImage(CGImageRef aInputImage, NSImage **aResult);
|
||||
|
||||
/** Creates a Cocoa <code>NSImage</code> from a frame of an <code>imgIContainer</code>.
|
||||
Combines the two methods above. The caller owns the <code>NSImage</code>.
|
||||
@param aImage the image to extract a frame from
|
||||
@param aWhichFrame the frame to extract (see imgIContainer FRAME_*)
|
||||
@param aResult the resulting NSImage
|
||||
@return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
|
||||
*/
|
||||
static nsresult CreateNSImageFromImageContainer(imgIContainer *aImage, PRUint32 aWhichFrame, NSImage **aResult);
|
||||
};
|
||||
|
||||
#endif // nsCocoaUtils_h_
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "gfxImageSurface.h"
|
||||
#include "nsCocoaUtils.h"
|
||||
#include "nsMenuBarX.h"
|
||||
#include "nsCocoaWindow.h"
|
||||
|
@ -243,3 +244,84 @@ void nsCocoaUtils::CleanUpAfterNativeAppModalDialog()
|
|||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
nsresult nsCocoaUtils::CreateCGImageFromImageContainer(imgIContainer *aImage, PRUint32 aWhichFrame, CGImageRef *aResult)
|
||||
{
|
||||
nsRefPtr<gfxImageSurface> frame;
|
||||
nsresult rv = aImage->CopyFrame(aWhichFrame,
|
||||
imgIContainer::FLAG_SYNC_DECODE,
|
||||
getter_AddRefs(frame));
|
||||
if (NS_FAILED(rv) || !frame) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PRInt32 width = frame->Width();
|
||||
PRInt32 stride = frame->Stride();
|
||||
PRInt32 height = frame->Height();
|
||||
if ((stride % 4 != 0) || (height < 1) || (width < 1)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Create a CGImageRef with the bits from the image, taking into account
|
||||
// the alpha ordering and endianness of the machine so we don't have to
|
||||
// touch the bits ourselves.
|
||||
CGDataProviderRef dataProvider = ::CGDataProviderCreateWithData(NULL,
|
||||
frame->Data(),
|
||||
stride * height,
|
||||
NULL);
|
||||
CGColorSpaceRef colorSpace = ::CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
||||
*aResult = ::CGImageCreate(width,
|
||||
height,
|
||||
8,
|
||||
32,
|
||||
stride,
|
||||
colorSpace,
|
||||
kCGBitmapByteOrder32Host | kCGImageAlphaFirst,
|
||||
dataProvider,
|
||||
NULL,
|
||||
0,
|
||||
kCGRenderingIntentDefault);
|
||||
::CGColorSpaceRelease(colorSpace);
|
||||
::CGDataProviderRelease(dataProvider);
|
||||
return *aResult ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult nsCocoaUtils::CreateNSImageFromCGImage(CGImageRef aInputImage, NSImage **aResult)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
PRInt32 width = ::CGImageGetWidth(aInputImage);
|
||||
PRInt32 height = ::CGImageGetHeight(aInputImage);
|
||||
NSRect imageRect = ::NSMakeRect(0.0, 0.0, width, height);
|
||||
|
||||
// Create a new image to receive the Quartz image data.
|
||||
*aResult = [[NSImage alloc] initWithSize:imageRect.size];
|
||||
|
||||
[*aResult lockFocus];
|
||||
|
||||
// Get the Quartz context and draw.
|
||||
CGContextRef imageContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
|
||||
::CGContextDrawImage(imageContext, *(CGRect*)&imageRect, aInputImage);
|
||||
|
||||
[*aResult unlockFocus];
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer *aImage, PRUint32 aWhichFrame, NSImage **aResult)
|
||||
{
|
||||
CGImageRef imageRef = NULL;
|
||||
nsresult rv = nsCocoaUtils::CreateCGImageFromImageContainer(aImage, aWhichFrame, &imageRef);
|
||||
if (NS_FAILED(rv) || !imageRef) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
rv = nsCocoaUtils::CreateNSImageFromCGImage(imageRef, aResult);
|
||||
if (NS_FAILED(rv) || !aResult) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
::CGImageRelease(imageRef);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
{
|
||||
@private
|
||||
NSMutableDictionary *mCursors;
|
||||
nsCursor mCurrentCursor;
|
||||
nsMacCursor *mCurrentMacCursor;
|
||||
}
|
||||
|
||||
/*! @method setCursor:
|
||||
|
@ -59,7 +59,18 @@
|
|||
Resources associated with the previous cursor are cleaned up.
|
||||
@param aCursor the cursor to use
|
||||
*/
|
||||
- (void) setCursor: (nsCursor) aCursor;
|
||||
- (nsresult) setCursor: (nsCursor) aCursor;
|
||||
|
||||
/*! @method setCursorWithImage:hotSpotX:hotSpotY:
|
||||
@abstract Sets the current cursor to a custom image
|
||||
@discussion Sets the current cursor to the cursor given by the aCursorImage argument.
|
||||
Resources associated with the previous cursor are cleaned up.
|
||||
@param aCursorImage the cursor image to use
|
||||
@param aHotSpotX the x coordinate of the cursor's hotspot
|
||||
@param aHotSpotY the y coordinate of the cursor's hotspot
|
||||
*/
|
||||
- (nsresult) setCursorWithImage: (imgIContainer*) aCursorImage hotSpotX: (PRUint32) aHotspotX hotSpotY: (PRUint32) aHotspotY;
|
||||
|
||||
|
||||
/*! @method sharedInstance
|
||||
@abstract Get the Singleton instance of the cursor manager.
|
||||
|
|
|
@ -35,12 +35,16 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "nsCocoaUtils.h"
|
||||
#include "nsCursorManager.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include <math.h>
|
||||
|
||||
static nsCursorManager *gInstance;
|
||||
static NSArray* sSpinCursorFrames = nil;
|
||||
static NSArray *sSpinCursorFrames = nil;
|
||||
static imgIContainer *sCursorImgContainer = nsnull;
|
||||
static const nsCursor sCustomCursor = eCursorCount;
|
||||
|
||||
/*! @category nsCursorManager(PrivateMethods)
|
||||
Private methods for the cursor manager class.
|
||||
|
@ -56,6 +60,15 @@ static NSArray* sSpinCursorFrames = nil;
|
|||
*/
|
||||
- (nsMacCursor *) getCursor: (nsCursor) aCursor;
|
||||
|
||||
/*! @method setMacCursor:
|
||||
@abstract Set the current Mac native cursor
|
||||
@discussion Sets the current cursor - this routine is what actually causes the cursor to change.
|
||||
The argument is retained and the old cursor is released.
|
||||
@param aMacCursor the cursor to set
|
||||
@result NS_OK
|
||||
*/
|
||||
- (nsresult) setMacCursor: (nsMacCursor*) aMacCursor;
|
||||
|
||||
/*! @method createCursor:
|
||||
@abstract Create a Mac native representation of a cursor.
|
||||
@discussion Creates a version of the Mac native representation of this cursor
|
||||
|
@ -101,7 +114,7 @@ static NSArray* sSpinCursorFrames = nil;
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
+ (nsMacCursor *) createCursor: (enum nsCursor) aCursor
|
||||
+ (nsMacCursor *) createCursor: (enum nsCursor) aCursor
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
|
@ -109,100 +122,100 @@ static NSArray* sSpinCursorFrames = nil;
|
|||
{
|
||||
SEL cursorSelector;
|
||||
case eCursor_standard:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor arrowCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor arrowCursor] type:aCursor];
|
||||
case eCursor_wait:
|
||||
case eCursor_spinning:
|
||||
return [nsMacCursor cursorWithFrames: sSpinCursorFrames];
|
||||
return [nsMacCursor cursorWithFrames:sSpinCursorFrames type:aCursor];
|
||||
case eCursor_select:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor IBeamCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor IBeamCursor] type:aCursor];
|
||||
case eCursor_hyperlink:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor pointingHandCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor pointingHandCursor] type:aCursor];
|
||||
case eCursor_crosshair:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor crosshairCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor crosshairCursor] type:aCursor];
|
||||
case eCursor_move:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor openHandCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor openHandCursor] type:aCursor];
|
||||
case eCursor_help:
|
||||
return [nsMacCursor cursorWithImageNamed: @"help" hotSpot: NSMakePoint(1,1)];
|
||||
return [nsMacCursor cursorWithImageNamed:@"help" hotSpot:NSMakePoint(1,1) type:aCursor];
|
||||
case eCursor_copy:
|
||||
cursorSelector = @selector(dragCopyCursor);
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor respondsToSelector: cursorSelector] ?
|
||||
[NSCursor performSelector: cursorSelector] :
|
||||
[NSCursor arrowCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor respondsToSelector:cursorSelector] ?
|
||||
[NSCursor performSelector:cursorSelector] :
|
||||
[NSCursor arrowCursor] type:aCursor];
|
||||
case eCursor_alias:
|
||||
cursorSelector = @selector(dragLinkCursor);
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor respondsToSelector: cursorSelector] ?
|
||||
[NSCursor performSelector: cursorSelector] :
|
||||
[NSCursor arrowCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor respondsToSelector:cursorSelector] ?
|
||||
[NSCursor performSelector:cursorSelector] :
|
||||
[NSCursor arrowCursor] type:aCursor];
|
||||
case eCursor_context_menu:
|
||||
cursorSelector = @selector(contextualMenuCursor);
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor respondsToSelector: cursorSelector] ?
|
||||
[NSCursor performSelector: cursorSelector] :
|
||||
[NSCursor arrowCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor respondsToSelector:cursorSelector] ?
|
||||
[NSCursor performSelector:cursorSelector] :
|
||||
[NSCursor arrowCursor] type:aCursor];
|
||||
case eCursor_cell:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor crosshairCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor crosshairCursor] type:aCursor];
|
||||
case eCursor_grab:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor openHandCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor openHandCursor] type:aCursor];
|
||||
case eCursor_grabbing:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor closedHandCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor closedHandCursor] type:aCursor];
|
||||
case eCursor_zoom_in:
|
||||
return [nsMacCursor cursorWithImageNamed: @"zoomIn" hotSpot: NSMakePoint(6,6)];
|
||||
return [nsMacCursor cursorWithImageNamed:@"zoomIn" hotSpot:NSMakePoint(6,6) type:aCursor];
|
||||
case eCursor_zoom_out:
|
||||
return [nsMacCursor cursorWithImageNamed: @"zoomOut" hotSpot: NSMakePoint(6,6)];
|
||||
return [nsMacCursor cursorWithImageNamed:@"zoomOut" hotSpot:NSMakePoint(6,6) type:aCursor];
|
||||
case eCursor_vertical_text:
|
||||
return [nsMacCursor cursorWithImageNamed: @"vtIBeam" hotSpot: NSMakePoint(7,8)];
|
||||
return [nsMacCursor cursorWithImageNamed:@"vtIBeam" hotSpot:NSMakePoint(7,8) type:aCursor];
|
||||
case eCursor_all_scroll:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor openHandCursor]];;
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor openHandCursor] type:aCursor];
|
||||
case eCursor_not_allowed:
|
||||
case eCursor_no_drop:
|
||||
cursorSelector = @selector(operationNotAllowedCursor);
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor respondsToSelector: cursorSelector] ?
|
||||
[NSCursor performSelector: cursorSelector] :
|
||||
[NSCursor arrowCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor respondsToSelector:cursorSelector] ?
|
||||
[NSCursor performSelector:cursorSelector] :
|
||||
[NSCursor arrowCursor] type:aCursor];
|
||||
// Resize Cursors:
|
||||
//North
|
||||
// North
|
||||
case eCursor_n_resize:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor resizeUpCursor]];
|
||||
//North East
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor resizeUpCursor] type:aCursor];
|
||||
// North East
|
||||
case eCursor_ne_resize:
|
||||
return [nsMacCursor cursorWithImageNamed: @"sizeNE" hotSpot: NSMakePoint(8,7)];
|
||||
//East
|
||||
case eCursor_e_resize:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor resizeRightCursor]];
|
||||
//South East
|
||||
return [nsMacCursor cursorWithImageNamed:@"sizeNE" hotSpot:NSMakePoint(8,7) type:aCursor];
|
||||
// East
|
||||
case eCursor_e_resize:
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor resizeRightCursor] type:aCursor];
|
||||
// South East
|
||||
case eCursor_se_resize:
|
||||
return [nsMacCursor cursorWithImageNamed: @"sizeSE" hotSpot: NSMakePoint(8,8)];
|
||||
//South
|
||||
return [nsMacCursor cursorWithImageNamed:@"sizeSE" hotSpot:NSMakePoint(8,8) type:aCursor];
|
||||
// South
|
||||
case eCursor_s_resize:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor resizeDownCursor]];
|
||||
//South West
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor resizeDownCursor] type:aCursor];
|
||||
// South West
|
||||
case eCursor_sw_resize:
|
||||
return [nsMacCursor cursorWithImageNamed: @"sizeSW" hotSpot: NSMakePoint(6,8)];
|
||||
//West
|
||||
return [nsMacCursor cursorWithImageNamed:@"sizeSW" hotSpot:NSMakePoint(6,8) type:aCursor];
|
||||
// West
|
||||
case eCursor_w_resize:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor resizeLeftCursor]];
|
||||
//North West
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor resizeLeftCursor] type:aCursor];
|
||||
// North West
|
||||
case eCursor_nw_resize:
|
||||
return [nsMacCursor cursorWithImageNamed: @"sizeNW" hotSpot: NSMakePoint(7,7)];
|
||||
//North & South
|
||||
return [nsMacCursor cursorWithImageNamed:@"sizeNW" hotSpot:NSMakePoint(7,7) type:aCursor];
|
||||
// North & South
|
||||
case eCursor_ns_resize:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor resizeUpDownCursor]];
|
||||
//East & West
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor resizeUpDownCursor] type:aCursor];
|
||||
// East & West
|
||||
case eCursor_ew_resize:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor resizeLeftRightCursor]];
|
||||
//North East & South West
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor resizeLeftRightCursor] type:aCursor];
|
||||
// North East & South West
|
||||
case eCursor_nesw_resize:
|
||||
return [nsMacCursor cursorWithImageNamed: @"sizeNESW" hotSpot: NSMakePoint(8,8)];
|
||||
//North West & South East
|
||||
return [nsMacCursor cursorWithImageNamed:@"sizeNESW" hotSpot:NSMakePoint(8,8) type:aCursor];
|
||||
// North West & South East
|
||||
case eCursor_nwse_resize:
|
||||
return [nsMacCursor cursorWithImageNamed: @"sizeNWSE" hotSpot: NSMakePoint(8,8)];
|
||||
//Column Resize
|
||||
return [nsMacCursor cursorWithImageNamed:@"sizeNWSE" hotSpot:NSMakePoint(8,8) type:aCursor];
|
||||
// Column Resize
|
||||
case eCursor_col_resize:
|
||||
return [nsMacCursor cursorWithImageNamed: @"colResize" hotSpot: NSMakePoint(8,8)];
|
||||
//Row Resize
|
||||
return [nsMacCursor cursorWithImageNamed:@"colResize" hotSpot:NSMakePoint(8,8) type:aCursor];
|
||||
// Row Resize
|
||||
case eCursor_row_resize:
|
||||
return [nsMacCursor cursorWithImageNamed: @"rowResize" hotSpot: NSMakePoint(8,8)];
|
||||
return [nsMacCursor cursorWithImageNamed:@"rowResize" hotSpot:NSMakePoint(8,8) type:aCursor];
|
||||
default:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor arrowCursor]];
|
||||
return [nsMacCursor cursorWithCursor:[NSCursor arrowCursor] type:aCursor];
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
|
@ -220,43 +233,100 @@ static NSArray* sSpinCursorFrames = nil;
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (void) setCursor: (enum nsCursor) aCursor
|
||||
- (nsresult) setCursor: (enum nsCursor) aCursor
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
// Some plugins mess with our cursors and set a cursor that even
|
||||
// [NSCursor currentCursor] doesn't know about. In case that happens, just
|
||||
// reset the state.
|
||||
[[NSCursor currentCursor] set];
|
||||
|
||||
nsMacCursor* currentCursor = [self getCursor: mCurrentCursor];
|
||||
|
||||
if (aCursor != mCurrentCursor || ![currentCursor isSet]) {
|
||||
[currentCursor unset];
|
||||
[[self getCursor: aCursor] set];
|
||||
}
|
||||
|
||||
if (mCurrentCursor != aCursor) {
|
||||
nsCursor oldType = [mCurrentMacCursor type];
|
||||
if (oldType != aCursor) {
|
||||
if (aCursor == eCursor_none) {
|
||||
[NSCursor hide];
|
||||
} else if (mCurrentCursor == eCursor_none) {
|
||||
} else if (oldType == eCursor_none) {
|
||||
[NSCursor unhide];
|
||||
}
|
||||
}
|
||||
[self setMacCursor:[self getCursor:aCursor]];
|
||||
|
||||
mCurrentCursor = aCursor;
|
||||
// if a custom cursor was previously set, release sCursorImgContainer
|
||||
if (oldType == sCustomCursor) {
|
||||
NS_IF_RELEASE(sCursorImgContainer);
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
- (nsresult) setMacCursor: (nsMacCursor*) aMacCursor
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (mCurrentMacCursor != aMacCursor || ![mCurrentMacCursor isSet]) {
|
||||
[aMacCursor retain];
|
||||
[mCurrentMacCursor unset];
|
||||
[aMacCursor set];
|
||||
[mCurrentMacCursor release];
|
||||
mCurrentMacCursor = aMacCursor;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
- (nsresult) setCursorWithImage: (imgIContainer*) aCursorImage hotSpotX: (PRUint32) aHotspotX hotSpotY: (PRUint32) aHotspotY
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
// As the user moves the mouse, this gets called repeatedly with the same aCursorImage
|
||||
if (sCursorImgContainer == aCursorImage && mCurrentMacCursor) {
|
||||
[self setMacCursor:mCurrentMacCursor];
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
[[NSCursor currentCursor] set];
|
||||
PRInt32 width = 0, height = 0;
|
||||
aCursorImage->GetWidth(&width);
|
||||
aCursorImage->GetHeight(&height);
|
||||
// prevent DoS attacks
|
||||
if (width > 128 || height > 128) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NSImage *cursorImage;
|
||||
nsresult rv = nsCocoaUtils::CreateNSImageFromImageContainer(aCursorImage, imgIContainer::FRAME_FIRST, &cursorImage);
|
||||
if (NS_FAILED(rv) || !cursorImage) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// if the hotspot is nonsensical, make it 0,0
|
||||
aHotspotX = (aHotspotX < 0 || aHotspotX > (PRUint32) width - 1) ? 0 :aHotspotX;
|
||||
aHotspotY = (aHotspotY < 0 || aHotspotY > (PRUint32) height - 1) ? 0 :aHotspotY;
|
||||
|
||||
NSPoint hotSpot = ::NSMakePoint(aHotspotX, aHotspotY);
|
||||
[self setMacCursor:[nsMacCursor cursorWithCursor:[[NSCursor alloc] initWithImage:cursorImage hotSpot:hotSpot] type:sCustomCursor]];
|
||||
[cursorImage release];
|
||||
|
||||
NS_IF_RELEASE(sCursorImgContainer);
|
||||
sCursorImgContainer = aCursorImage;
|
||||
NS_ADDREF(sCursorImgContainer);
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
- (nsMacCursor *) getCursor: (enum nsCursor) aCursor
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
nsMacCursor * result = [mCursors objectForKey: [NSNumber numberWithInt: aCursor]];
|
||||
nsMacCursor * result = [mCursors objectForKey:[NSNumber numberWithInt:aCursor]];
|
||||
if (!result) {
|
||||
result = [nsCursorManager createCursor: aCursor];
|
||||
[mCursors setObject: result forKey: [NSNumber numberWithInt: aCursor]];
|
||||
result = [nsCursorManager createCursor:aCursor];
|
||||
[mCursors setObject:result forKey:[NSNumber numberWithInt:aCursor]];
|
||||
}
|
||||
return result;
|
||||
|
||||
|
@ -267,8 +337,10 @@ static NSArray* sSpinCursorFrames = nil;
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
[[self getCursor: mCurrentCursor] unset];
|
||||
[mCursors release];
|
||||
[mCurrentMacCursor unset];
|
||||
[mCurrentMacCursor release];
|
||||
[mCursors release];
|
||||
NS_IF_RELEASE(sCursorImgContainer);
|
||||
[super dealloc];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#define nsMacCursor_h_
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "nsIWidget.h"
|
||||
|
||||
/*! @class nsMacCursor
|
||||
@abstract Represents a native Mac cursor.
|
||||
|
@ -49,6 +50,7 @@
|
|||
@private
|
||||
NSTimer *mTimer;
|
||||
@protected
|
||||
nsCursor mType;
|
||||
int mFrameCounter;
|
||||
}
|
||||
|
||||
|
@ -56,11 +58,12 @@
|
|||
@abstract Create a cursor by specifying a Cocoa <code>NSCursor</code>.
|
||||
@discussion Creates a cursor representing the given Cocoa built-in cursor.
|
||||
@param aCursor the <code>NSCursor</code> to use
|
||||
@param aType the corresponding <code>nsCursor</code> constant
|
||||
@result an autoreleased instance of <code>nsMacCursor</code> representing the given <code>NSCursor</code>
|
||||
*/
|
||||
+ (nsMacCursor *) cursorWithCursor: (NSCursor *) aCursor;
|
||||
+ (nsMacCursor *) cursorWithCursor: (NSCursor *) aCursor type: (nsCursor) aType;
|
||||
|
||||
/*! @method cursorWithImageNamed:hotSpot:
|
||||
/*! @method cursorWithImageNamed:hotSpot:type:
|
||||
@abstract Create a cursor by specifying the name of an image resource to use for the cursor and a hotspot.
|
||||
@discussion Creates a cursor by loading the named image using the <code>+[NSImage imageNamed:]</code> method.
|
||||
<p>The image must be compatible with any restrictions laid down by <code>NSCursor</code>. These vary
|
||||
|
@ -68,19 +71,21 @@
|
|||
<p>The hotspot precisely determines the point where the user clicks when using the cursor.</p>
|
||||
@param aCursor the name of the image to use for the cursor
|
||||
@param aPoint the point within the cursor to use as the hotspot
|
||||
@param aType the corresponding <code>nsCursor</code> constant
|
||||
@result an autoreleased instance of <code>nsMacCursor</code> that uses the given image and hotspot
|
||||
*/
|
||||
+ (nsMacCursor *) cursorWithImageNamed: (NSString *) aCursorImage hotSpot: (NSPoint) aPoint;
|
||||
+ (nsMacCursor *) cursorWithImageNamed: (NSString *) aCursorImage hotSpot: (NSPoint) aPoint type: (nsCursor) aType;
|
||||
|
||||
/*! @method cursorWithFrames:
|
||||
/*! @method cursorWithFrames:type:
|
||||
@abstract Create an animated cursor by specifying the frames to use for the animation.
|
||||
@discussion Creates a cursor that will animate by cycling through the given frames. Each element of the array
|
||||
must be an instance of <code>NSCursor</code>
|
||||
@param aCursorFrames an array of <code>NSCursor</code>, representing the frames of an animated cursor, in the
|
||||
order they should be played.
|
||||
@param aType the corresponding <code>nsCursor</code> constant
|
||||
@result an autoreleased instance of <code>nsMacCursor</code> that will animate the given cursor frames
|
||||
*/
|
||||
+ (nsMacCursor *) cursorWithFrames: (NSArray *) aCursorFrames;
|
||||
+ (nsMacCursor *) cursorWithFrames: (NSArray *) aCursorFrames type: (nsCursor) aType;
|
||||
|
||||
/*! @method cocoaCursorWithImageNamed:hotSpot:
|
||||
@abstract Create a Cocoa NSCursor object with a Gecko image resource name and a hotspot point.
|
||||
|
@ -118,6 +123,14 @@
|
|||
*/
|
||||
- (BOOL) isAnimated;
|
||||
|
||||
/** @method cursorType
|
||||
@abstract Get the cursor type for this cursor
|
||||
@discussion This method returns the <code>nsCursor</code> constant that corresponds to this cursor, which is
|
||||
equivalent to the CSS name for the cursor.
|
||||
@result The nsCursor constant corresponding to this cursor, or nsCursor's 'eCursorCount' if the cursor
|
||||
is a custom cursor loaded from a URI
|
||||
*/
|
||||
- (nsCursor) type;
|
||||
@end
|
||||
|
||||
#endif // nsMacCursor_h_
|
||||
|
|
|
@ -118,17 +118,19 @@
|
|||
must be an instance of <code>NSCursor</code>
|
||||
@param aCursorFrames an array of <code>NSCursor</code>, representing the frames of an animated cursor, in the
|
||||
order they should be played.
|
||||
@param aType the corresponding <code>nsCursor</code> constant
|
||||
@result an instance of <code>nsCocoaCursor</code> that will animate the given cursor frames
|
||||
*/
|
||||
- (id) initWithFrames: (NSArray *) aCursorFrames;
|
||||
- (id) initWithFrames: (NSArray *) aCursorFrames type: (nsCursor) aType;
|
||||
|
||||
/*! @method initWithCursor:
|
||||
@abstract Create a cursor by specifying a Cocoa <code>NSCursor</code>.
|
||||
@discussion Creates a cursor representing the given Cocoa built-in cursor.
|
||||
@param aCursor the <code>NSCursor</code> to use
|
||||
@param aType the corresponding <code>nsCursor</code> constant
|
||||
@result an instance of <code>nsCocoaCursor</code> representing the given <code>NSCursor</code>
|
||||
*/
|
||||
- (id) initWithCursor: (NSCursor *) aCursor;
|
||||
- (id) initWithCursor: (NSCursor *) aCursor type: (nsCursor) aType;
|
||||
|
||||
/*! @method initWithImageNamed:hotSpot:
|
||||
@abstract Create a cursor by specifying the name of an image resource to use for the cursor and a hotspot.
|
||||
|
@ -138,37 +140,38 @@
|
|||
<p>The hotspot precisely determines the point where the user clicks when using the cursor.</p>
|
||||
@param aCursor the name of the image to use for the cursor
|
||||
@param aPoint the point within the cursor to use as the hotspot
|
||||
@param aType the corresponding <code>nsCursor</code> constant
|
||||
@result an instance of <code>nsCocoaCursor</code> that uses the given image and hotspot
|
||||
*/
|
||||
- (id) initWithImageNamed: (NSString *) aCursorImage hotSpot: (NSPoint) aPoint;
|
||||
- (id) initWithImageNamed: (NSString *) aCursorImage hotSpot: (NSPoint) aPoint type: (nsCursor) aType;
|
||||
|
||||
@end
|
||||
|
||||
@implementation nsMacCursor
|
||||
|
||||
+ (nsMacCursor *) cursorWithCursor: (NSCursor *) aCursor
|
||||
+ (nsMacCursor *) cursorWithCursor: (NSCursor *) aCursor type: (nsCursor) aType
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
return [[[nsCocoaCursor alloc] initWithCursor: aCursor] autorelease];
|
||||
return [[[nsCocoaCursor alloc] initWithCursor:aCursor type:aType] autorelease];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
+ (nsMacCursor *) cursorWithImageNamed: (NSString *) aCursorImage hotSpot: (NSPoint) aPoint
|
||||
+ (nsMacCursor *) cursorWithImageNamed: (NSString *) aCursorImage hotSpot: (NSPoint) aPoint type: (nsCursor) aType
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
return [[[nsCocoaCursor alloc] initWithImageNamed: aCursorImage hotSpot: aPoint] autorelease];
|
||||
return [[[nsCocoaCursor alloc] initWithImageNamed:aCursorImage hotSpot:aPoint type:aType] autorelease];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
+ (nsMacCursor *) cursorWithFrames: (NSArray *) aCursorFrames
|
||||
+ (nsMacCursor *) cursorWithFrames: (NSArray *) aCursorFrames type: (nsCursor) aType
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
return [[[nsCocoaCursor alloc] initWithFrames: aCursorFrames] autorelease];
|
||||
return [[[nsCocoaCursor alloc] initWithFrames:aCursorFrames type:aType] autorelease];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
@ -201,7 +204,7 @@
|
|||
cursorImage = [[[NSImage alloc] initWithContentsOfFile:pathToImage] autorelease];
|
||||
if (!cursorImage)
|
||||
goto INIT_FAILURE;
|
||||
return [[[NSCursor alloc] initWithImage: cursorImage hotSpot: aPoint] autorelease];
|
||||
return [[[NSCursor alloc] initWithImage:cursorImage hotSpot:aPoint] autorelease];
|
||||
|
||||
INIT_FAILURE:
|
||||
NS_WARNING("Problem getting path to cursor image file!");
|
||||
|
@ -222,9 +225,9 @@ INIT_FAILURE:
|
|||
if ([self isAnimated]) {
|
||||
[self createTimer];
|
||||
}
|
||||
//if the cursor isn't animated or the timer creation fails for any reason...
|
||||
// if the cursor isn't animated or the timer creation fails for any reason...
|
||||
if (!mTimer) {
|
||||
[self setFrame: 0];
|
||||
[self setFrame:0];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,7 +243,7 @@ INIT_FAILURE:
|
|||
|
||||
- (int) numFrames
|
||||
{
|
||||
//subclasses need to override this to support animation
|
||||
// subclasses need to override this to support animation
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -255,11 +258,11 @@ INIT_FAILURE:
|
|||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (!mTimer) {
|
||||
mTimer = [[NSTimer scheduledTimerWithTimeInterval: 0.25
|
||||
target: self
|
||||
selector: @selector(advanceAnimatedCursor:)
|
||||
userInfo: nil
|
||||
repeats: YES] retain];
|
||||
mTimer = [[NSTimer scheduledTimerWithTimeInterval:0.25
|
||||
target:self
|
||||
selector:@selector(advanceAnimatedCursor:)
|
||||
userInfo:nil
|
||||
repeats:YES] retain];
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
|
@ -283,7 +286,7 @@ INIT_FAILURE:
|
|||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if ([aTimer isValid]) {
|
||||
[self setFrame: [self getNextCursorFrame]];
|
||||
[self setFrame:[self getNextCursorFrame]];
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
|
@ -291,7 +294,11 @@ INIT_FAILURE:
|
|||
|
||||
- (void) setFrame: (int) aFrameIndex
|
||||
{
|
||||
//subclasses need to do something useful here
|
||||
// subclasses need to do something useful here
|
||||
}
|
||||
|
||||
- (nsCursor) type {
|
||||
return mType;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
|
@ -308,7 +315,7 @@ INIT_FAILURE:
|
|||
|
||||
@implementation nsCocoaCursor
|
||||
|
||||
- (id) initWithFrames: (NSArray *) aCursorFrames
|
||||
- (id) initWithFrames: (NSArray *) aCursorFrames type: (nsCursor) aType
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
|
@ -316,30 +323,31 @@ INIT_FAILURE:
|
|||
NSEnumerator *it = [aCursorFrames objectEnumerator];
|
||||
NSObject *frame = nil;
|
||||
while ((frame = [it nextObject])) {
|
||||
NS_ASSERTION([frame isKindOfClass: [NSCursor class]], "Invalid argument: All frames must be of type NSCursor");
|
||||
NS_ASSERTION([frame isKindOfClass:[NSCursor class]], "Invalid argument: All frames must be of type NSCursor");
|
||||
}
|
||||
mFrames = [aCursorFrames retain];
|
||||
mFrameCounter = 0;
|
||||
mType = aType;
|
||||
return self;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id) initWithCursor: (NSCursor *) aCursor
|
||||
- (id) initWithCursor: (NSCursor *) aCursor type: (nsCursor) aType
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
NSArray *frame = [NSArray arrayWithObjects: aCursor, nil];
|
||||
return [self initWithFrames: frame];
|
||||
NSArray *frame = [NSArray arrayWithObjects:aCursor, nil];
|
||||
return [self initWithFrames:frame type:aType];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id) initWithImageNamed: (NSString *) aCursorImage hotSpot: (NSPoint) aPoint
|
||||
- (id) initWithImageNamed: (NSString *) aCursorImage hotSpot: (NSPoint) aPoint type: (nsCursor) aType
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
return [self initWithCursor: [nsMacCursor cocoaCursorWithImageNamed: aCursorImage hotSpot: aPoint]];
|
||||
return [self initWithCursor:[nsMacCursor cocoaCursorWithImageNamed:aCursorImage hotSpot:aPoint] type:aType];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
@ -353,7 +361,7 @@ INIT_FAILURE:
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NSCursor* newCursor = [mFrames objectAtIndex: aFrameIndex];
|
||||
NSCursor* newCursor = [mFrames objectAtIndex:aFrameIndex];
|
||||
[newCursor set];
|
||||
mLastSetCocoaCursor = newCursor;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче