зеркало из https://github.com/mozilla/pjs.git
animated cursors for cocoa widget, like we did for carbon (bug 208717)
This commit is contained in:
Родитель
1d237e8381
Коммит
28f2eb8765
|
@ -112,6 +112,8 @@ CMMSRCS = \
|
|||
nsChildView.mm \
|
||||
nsWidgetFactory.mm \
|
||||
nsNativeScrollbar.mm \
|
||||
nsCursorManager.mm \
|
||||
nsMacCursor.mm \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS += \
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "nsCursorManager.h"
|
||||
|
||||
@interface ChildView(Private)
|
||||
|
||||
|
@ -116,7 +116,6 @@ nsIWidget * gRollupWidget = nsnull;
|
|||
static NMRec gNMRec;
|
||||
static Boolean gNotificationInstalled = false;
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
//#define PAINT_DEBUGGING // flash areas as they are painted
|
||||
|
@ -904,59 +903,7 @@ nsIMenuBar* nsChildView::GetMenuBar()
|
|||
NS_METHOD nsChildView::SetCursor(nsCursor aCursor)
|
||||
{
|
||||
nsBaseWidget::SetCursor(aCursor);
|
||||
|
||||
short cursor = -1;
|
||||
switch (aCursor)
|
||||
{
|
||||
case eCursor_standard: cursor = kThemeArrowCursor; break;
|
||||
case eCursor_wait: cursor = kThemeWatchCursor; break;
|
||||
case eCursor_select: cursor = kThemeIBeamCursor; break;
|
||||
case eCursor_hyperlink: cursor = kThemePointingHandCursor; break;
|
||||
case eCursor_sizeWE: cursor = kThemeResizeLeftRightCursor; break;
|
||||
case eCursor_sizeNS: cursor = 129; break;
|
||||
case eCursor_sizeNW: cursor = 130; break;
|
||||
case eCursor_sizeSE: cursor = 131; break;
|
||||
case eCursor_sizeNE: cursor = 132; break;
|
||||
case eCursor_sizeSW: cursor = 133; break;
|
||||
case eCursor_arrow_north: cursor = 134; break;
|
||||
case eCursor_arrow_north_plus:cursor = 135; break;
|
||||
case eCursor_arrow_south: cursor = 136; break;
|
||||
case eCursor_arrow_south_plus:cursor = 137; break;
|
||||
case eCursor_arrow_west: cursor = 138; break;
|
||||
case eCursor_arrow_west_plus: cursor = 139; break;
|
||||
case eCursor_arrow_east: cursor = 140; break;
|
||||
case eCursor_arrow_east_plus: cursor = 141; break;
|
||||
case eCursor_crosshair: cursor = kThemeCrossCursor; break;
|
||||
case eCursor_move: cursor = kThemeOpenHandCursor; break;
|
||||
case eCursor_help: cursor = 143; break;
|
||||
case eCursor_copy: cursor = 144; break; // CSS3
|
||||
case eCursor_alias: cursor = 145; break;
|
||||
case eCursor_context_menu: cursor = 146; break;
|
||||
case eCursor_cell: cursor = kThemePlusCursor; break;
|
||||
case eCursor_grab: cursor = kThemeOpenHandCursor; break;
|
||||
case eCursor_grabbing: cursor = kThemeClosedHandCursor; break;
|
||||
case eCursor_spinning: cursor = 200; break; // better than kThemeSpinningCursor
|
||||
case eCursor_count_up: cursor = kThemeCountingUpHandCursor; break;
|
||||
case eCursor_count_down: cursor = kThemeCountingDownHandCursor; break;
|
||||
case eCursor_count_up_down: cursor = kThemeCountingUpAndDownHandCursor; break;
|
||||
case eCursor_zoom_in: cursor = 149; break;
|
||||
case eCursor_zoom_out: cursor = 150; break;
|
||||
}
|
||||
if (cursor >= 0)
|
||||
{
|
||||
if (cursor >= 128)
|
||||
{
|
||||
nsMacResources::OpenLocalResourceFile();
|
||||
CursHandle cursHandle = ::GetCursor(cursor);
|
||||
NS_ASSERTION ( cursHandle, "Can't load cursor, is the resource file installed correctly?" );
|
||||
if ( cursHandle )
|
||||
::SetCursor(*cursHandle);
|
||||
nsMacResources::CloseLocalResourceFile();
|
||||
}
|
||||
else
|
||||
::SetThemeCursor(cursor);
|
||||
}
|
||||
|
||||
[[nsCursorManager sharedInstance] setCursor: aCursor];
|
||||
return NS_OK;
|
||||
} // nsChildView::SetCursor
|
||||
|
||||
|
@ -1338,6 +1285,7 @@ NS_IMETHODIMP nsChildView::Invalidate(PRBool aIsSynchronous)
|
|||
if (!mView || !mVisible)
|
||||
return NS_OK;
|
||||
|
||||
printf(". invalidate full widget\n");
|
||||
if (aIsSynchronous)
|
||||
[mView display];
|
||||
else
|
||||
|
@ -1359,6 +1307,7 @@ NS_IMETHODIMP nsChildView::Invalidate(const nsRect &aRect, PRBool aIsSynchronous
|
|||
NSRect r;
|
||||
ConvertGeckoToCocoaRect ( aRect, r );
|
||||
|
||||
printf(". invalidate rect\n");
|
||||
if (aIsSynchronous)
|
||||
[mView displayRect:r];
|
||||
else
|
||||
|
@ -1375,6 +1324,7 @@ NS_IMETHODIMP nsChildView::Invalidate(const nsRect &aRect, PRBool aIsSynchronous
|
|||
//-------------------------------------------------------------------------
|
||||
NS_IMETHODIMP nsChildView::Validate()
|
||||
{
|
||||
printf(". validate full widget\n");
|
||||
[mView setNeedsDisplay:NO];
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1398,6 +1348,7 @@ NS_IMETHODIMP nsChildView::InvalidateRegion(const nsIRegion *aRegion, PRBool aIs
|
|||
region->GetBoundingBox ( &bounds.x, &bounds.y, &bounds.width, &bounds.height );
|
||||
ConvertGeckoToCocoaRect(bounds, r);
|
||||
|
||||
printf(". invalidate region\n");
|
||||
if ( aIsSynchronous )
|
||||
[mView displayRect:r];
|
||||
else
|
||||
|
@ -2476,6 +2427,7 @@ nsChildView::Idle()
|
|||
}
|
||||
|
||||
// tell gecko to paint.
|
||||
printf("- drawRect in nsChildView\n");
|
||||
nsRect r;
|
||||
ConvertCocoaToGeckoRect(aRect, r);
|
||||
nsCOMPtr<nsIRenderingContext> rendContext = getter_AddRefs(mGeckoChild->GetRenderingContext());
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is nsCursors.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Andrew Thompson.
|
||||
* Portions created by the Andrew Thompson are Copyright (C) 2004
|
||||
* Andrew Thompson. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "nsIWidget.h"
|
||||
#import "nsMacCursor.h"
|
||||
|
||||
/*! @class nsCursorManager
|
||||
@abstract Singleton service provides access to all cursors available in the application.
|
||||
@discussion Use <code>nsCusorManager</code> to set the current cursor using an XP <code>nsCusor</code> enum value.
|
||||
<code>nsCursorManager</code> encapsulates the details of setting different types of cursors, animating
|
||||
cursors and cleaning up cursors when they are no longer in use.
|
||||
*/
|
||||
@interface nsCursorManager : NSObject
|
||||
{
|
||||
@private
|
||||
NSMutableDictionary *mCursors;
|
||||
nsCursor mCurrentCursor;
|
||||
}
|
||||
|
||||
/*! @method setCursor:
|
||||
@abstract Sets the current cursor.
|
||||
@discussion Sets the current cursor to the cursor indicated by the XP cursor constant given as an argument.
|
||||
Resources associated with the previous cursor are cleaned up.
|
||||
@param aCursor the cursor to use
|
||||
*/
|
||||
- (void) setCursor: (nsCursor) aCursor;
|
||||
|
||||
/*! @method sharedInstance
|
||||
@abstract Get the Singleton instance of the cursor manager.
|
||||
@discussion Use this method to obtain a reference to the cursor manager.
|
||||
@result a reference to the cursor manager
|
||||
*/
|
||||
+ (nsCursorManager *) sharedInstance;
|
||||
|
||||
/*! @method dispose
|
||||
@abstract Releases the shared instance of the cursor manager.
|
||||
@discussion Use dispose to clean up the cursor manager and associated cursors.
|
||||
*/
|
||||
+ (void) dispose;
|
||||
@end
|
|
@ -0,0 +1,242 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is nsCursors.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Andrew Thompson.
|
||||
* Portions created by the Andrew Thompson are Copyright (C) 2004
|
||||
* Andrew Thompson. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "nsCursorManager.h"
|
||||
#import "math.h"
|
||||
|
||||
static nsCursorManager *gInstance;
|
||||
|
||||
/*! @category nsCursorManager(PrivateMethods)
|
||||
Private methods for the cursor manager class.
|
||||
*/
|
||||
@interface nsCursorManager(PrivateMethods)
|
||||
/*! @method getCursor:
|
||||
@abstract Get a reference to the native Mac representation of a cursor.
|
||||
@discussion Gets a reference to the Mac native implementation of a cursor.
|
||||
If the cursor has been requested before, it is retreived from the cursor cache, otherwise is it created
|
||||
and cached.
|
||||
@param aCursor the cursor to get
|
||||
@result the Mac native implementation of the cursor
|
||||
*/
|
||||
- (nsMacCursor *) getCursor: (nsCursor) aCursor;
|
||||
|
||||
/*! @method createCursor:
|
||||
@abstract Create a Mac native representation of a cursor.
|
||||
@discussion Creates a version of the Mac native representation of this cursor suitable for use on this version of
|
||||
Mac OS X
|
||||
@param aCursor the cursor to create
|
||||
@result the Mac native implementation of the cursor
|
||||
*/
|
||||
+ (nsMacCursor *) createCursor: (enum nsCursor) aCursor;
|
||||
|
||||
/*! @method createNSCursor:orThemeCursor:
|
||||
@abstract Creates the appropriate cursor implementation from the arguments.
|
||||
@discussion Creates a native Mac cursor, using NSCursor if the cursor is available on this version of Mac OS X,
|
||||
otherwise falls back to creating a traditional Carbon AppearanceManager ThemeCursor.
|
||||
@param aPantherCursor selector indicating the NSCursor cursor to create if on Panther or later
|
||||
@param aJaguarCursor the ThemeCursor to use as an alternative if running on Jaguar
|
||||
@result the Mac native implementation of the cursor
|
||||
*/
|
||||
+ (nsMacCursor *) createNSCursor: (SEL) aPantherCursor orThemeCursor: (ThemeCursor) aJaguarCursor;
|
||||
|
||||
/*! @method createNSCursor:orImageCursor:withHotspot:
|
||||
@abstract Creates the appropriate cursor implementation from the arguments.
|
||||
@discussion Creates a native Mac cursor, using NSCursor if the cursor is available on this version of Mac OS X,
|
||||
otherwise falls back to creating an NSCursor instance from a custom image and hotspot.
|
||||
@param aPantherCursor selector indicating the NSCursor cursor to create if on Panther or later
|
||||
@param aImageName the name of the image to use for the cursor as the cursor on Jagua
|
||||
@param aPoint the hotspot to use with the image to form a cursor on Jaguar
|
||||
@result the Mac native implementation of the cursor
|
||||
*/
|
||||
+ (nsMacCursor *) createNSCursor: (SEL) aPantherCursor orImageCursor: (NSString *) aImageName withHotspot: (NSPoint) aPoint;
|
||||
@end
|
||||
|
||||
/*! @function isPantherOrLater
|
||||
@abstract Determine whether we are running on Panther (Mac OS X 10.3) or later
|
||||
@result YES if the current operating system version is 10.3 or later, else NO
|
||||
*/
|
||||
static BOOL isPantherOrLater();
|
||||
|
||||
static BOOL isPantherOrLater()
|
||||
{
|
||||
static PRBool gInitVer = PR_FALSE;
|
||||
static PRBool gOnPantherOrLater = PR_FALSE;
|
||||
if(!gInitVer)
|
||||
{
|
||||
long version;
|
||||
OSErr err = ::Gestalt(gestaltSystemVersion, &version);
|
||||
gOnPantherOrLater = (err == noErr && version >= 0x00001030);
|
||||
gInitVer = PR_TRUE;
|
||||
}
|
||||
return gOnPantherOrLater;
|
||||
}
|
||||
|
||||
@implementation nsCursorManager
|
||||
|
||||
+ (nsCursorManager *) sharedInstance
|
||||
{
|
||||
if (gInstance == nil)
|
||||
{
|
||||
gInstance = [[nsCursorManager alloc] init];
|
||||
}
|
||||
return gInstance;
|
||||
}
|
||||
|
||||
+ (void) dispose
|
||||
{
|
||||
[gInstance release];
|
||||
gInstance = nil;
|
||||
}
|
||||
|
||||
+ (nsMacCursor *) createCursor: (enum nsCursor) aCursor
|
||||
{
|
||||
switch(aCursor)
|
||||
{
|
||||
case eCursor_standard:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor arrowCursor]];
|
||||
case eCursor_wait:
|
||||
return [nsMacCursor cursorWithThemeCursor: kThemeWatchCursor];
|
||||
case eCursor_select:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor IBeamCursor]];
|
||||
case eCursor_hyperlink:
|
||||
return [nsCursorManager createNSCursor: @selector(pointingHandCursor) orThemeCursor: kThemePointingHandCursor];
|
||||
case eCursor_sizeWE:
|
||||
return [nsCursorManager createNSCursor: @selector(resizeLeftRightCursor) orThemeCursor: kThemeResizeLeftRightCursor];
|
||||
case eCursor_sizeNS:
|
||||
return [nsCursorManager createNSCursor: @selector(resizeUpDownCursor) orImageCursor: @"sizeNS" withHotspot: NSMakePoint(7,7)];
|
||||
case eCursor_sizeNW:
|
||||
return [nsMacCursor cursorWithImageNamed: @"sizeNW" hotSpot: NSMakePoint(7,7)];
|
||||
case eCursor_sizeSE:
|
||||
return [nsMacCursor cursorWithImageNamed: @"sizeSE" hotSpot: NSMakePoint(8,8)];
|
||||
case eCursor_sizeNE:
|
||||
return [nsMacCursor cursorWithImageNamed: @"sizeNE" hotSpot: NSMakePoint(8,7)];
|
||||
case eCursor_sizeSW:
|
||||
return [nsMacCursor cursorWithImageNamed: @"sizeSW" hotSpot: NSMakePoint(6,8)];
|
||||
case eCursor_arrow_north:
|
||||
case eCursor_arrow_north_plus:
|
||||
return [nsCursorManager createNSCursor: @selector(resizeUpCursor) orImageCursor: @"arrowN" withHotspot: NSMakePoint(7,7)];
|
||||
case eCursor_arrow_south:
|
||||
case eCursor_arrow_south_plus:
|
||||
return [nsCursorManager createNSCursor: @selector(resizeDownCursor) orImageCursor: @"arrowS" withHotspot: NSMakePoint(7,7)];
|
||||
case eCursor_arrow_west:
|
||||
case eCursor_arrow_west_plus:
|
||||
return [nsCursorManager createNSCursor: @selector(resizeLeftCursor) orThemeCursor: kThemeResizeLeftCursor];
|
||||
case eCursor_arrow_east:
|
||||
case eCursor_arrow_east_plus:
|
||||
return [nsCursorManager createNSCursor: @selector(resizeRightCursor) orThemeCursor: kThemeResizeRightCursor];
|
||||
case eCursor_crosshair:
|
||||
return [nsCursorManager createNSCursor: @selector(crosshairCursor) orThemeCursor: kThemeCrossCursor];
|
||||
case eCursor_move:
|
||||
return [nsCursorManager createNSCursor: @selector(openHandCursor) orThemeCursor: kThemeOpenHandCursor];
|
||||
case eCursor_help:
|
||||
return [nsMacCursor cursorWithImageNamed: @"help" hotSpot: NSMakePoint(1,1)];
|
||||
case eCursor_copy:
|
||||
return [nsMacCursor cursorWithThemeCursor: kThemeCopyArrowCursor];
|
||||
case eCursor_alias:
|
||||
return [nsMacCursor cursorWithThemeCursor: kThemeAliasArrowCursor];
|
||||
case eCursor_context_menu:
|
||||
return [nsMacCursor cursorWithImageNamed: @"contextMenu" hotSpot: NSMakePoint(1,1)];
|
||||
case eCursor_cell:
|
||||
return [nsMacCursor cursorWithThemeCursor: kThemePlusCursor];
|
||||
case eCursor_grab:
|
||||
return [nsCursorManager createNSCursor: @selector(openHandCursor) orThemeCursor: kThemeOpenHandCursor];
|
||||
case eCursor_grabbing:
|
||||
return [nsCursorManager createNSCursor: @selector(closedHandCursor) orThemeCursor: kThemeClosedHandCursor];
|
||||
case eCursor_spinning:
|
||||
return [nsMacCursor cursorWithResources: 200 lastFrame: 203]; // better than kThemeSpinningCursor
|
||||
case eCursor_count_up:
|
||||
return [nsMacCursor cursorWithThemeCursor: kThemeCountingUpHandCursor];
|
||||
case eCursor_count_down:
|
||||
return [nsMacCursor cursorWithThemeCursor: kThemeCountingDownHandCursor];
|
||||
case eCursor_count_up_down:
|
||||
return [nsMacCursor cursorWithThemeCursor: kThemeCountingUpAndDownHandCursor];
|
||||
case eCursor_zoom_in:
|
||||
return [nsMacCursor cursorWithImageNamed: @"zoomIn" hotSpot: NSMakePoint(6,6)];
|
||||
case eCursor_zoom_out:
|
||||
return [nsMacCursor cursorWithImageNamed: @"zoomOut" hotSpot: NSMakePoint(6,6)];
|
||||
default:
|
||||
return [nsMacCursor cursorWithCursor: [NSCursor arrowCursor]];
|
||||
}
|
||||
}
|
||||
|
||||
+ (nsMacCursor *) createNSCursor: (SEL) aPantherCursor orThemeCursor: (ThemeCursor) aJaguarCursor
|
||||
{
|
||||
return isPantherOrLater() ? [nsMacCursor cursorWithCursor: [NSCursor performSelector: aPantherCursor]] :
|
||||
[nsMacCursor cursorWithThemeCursor: aJaguarCursor];
|
||||
}
|
||||
|
||||
+ (nsMacCursor *) createNSCursor: (SEL) aPantherCursor orImageCursor: (NSString *) aImageName withHotspot: (NSPoint) aPoint
|
||||
{
|
||||
return isPantherOrLater() ? [nsMacCursor cursorWithCursor: [NSCursor performSelector: aPantherCursor]] :
|
||||
[nsMacCursor cursorWithImageNamed: aImageName hotSpot: aPoint];
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
if ( (self = [super init]) )
|
||||
{
|
||||
mCursors = [[NSMutableDictionary alloc] initWithCapacity: 25];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) setCursor: (enum nsCursor) aCursor
|
||||
{
|
||||
if (aCursor != mCurrentCursor)
|
||||
{
|
||||
[[self getCursor: mCurrentCursor] unset];
|
||||
[[self getCursor: aCursor] set];
|
||||
mCurrentCursor = aCursor;
|
||||
}
|
||||
}
|
||||
|
||||
- (nsMacCursor *) getCursor: (enum nsCursor) aCursor
|
||||
{
|
||||
nsMacCursor * result = [mCursors objectForKey: [NSNumber numberWithInt: aCursor]];
|
||||
if ( result == nil )
|
||||
{
|
||||
result = [nsCursorManager createCursor: aCursor];
|
||||
[mCursors setObject: result forKey: [NSNumber numberWithInt: aCursor]];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[[self getCursor: mCurrentCursor] unset];
|
||||
[mCursors release];
|
||||
[super dealloc];
|
||||
}
|
||||
@end
|
|
@ -0,0 +1,121 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is nsCursors.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Andrew Thompson.
|
||||
* Portions created by the Andrew Thompson are Copyright (C) 2004
|
||||
* Andrew Thompson. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
/*! @class nsMacCursor
|
||||
@abstract Represents a native Mac cursor.
|
||||
@discussion <code>nsMacCursor</code> provides a simple API for creating and working with native Macintosh cursors.
|
||||
Cursors can be created used without needing to be aware of the way different cursors are implemented,
|
||||
in particular the details of managing an animated cursor are hidden.
|
||||
*/
|
||||
@interface nsMacCursor : NSObject
|
||||
{
|
||||
@private
|
||||
NSTimer *mTimer;
|
||||
int mFrameCounter;
|
||||
}
|
||||
|
||||
/*! @method cursorWithThemeCursor:
|
||||
@abstract Create a cursor by specifying a Carbon Apperance Manager <code>ThemeCursor</code> constant.
|
||||
@discussion Creates a cursor representing the given Appearance Manager built in cursor.
|
||||
@param aCursor the <code>ThemeCursor</code> to use
|
||||
@result an autoreleased instance of <code>nsMacCursor</code> representing the given <code>ThemeCursor</code>
|
||||
*/
|
||||
+ (nsMacCursor *) cursorWithThemeCursor: (ThemeCursor) aCursor;
|
||||
|
||||
/*! @method cursorWithCursor:
|
||||
@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
|
||||
@result an autoreleased instance of <code>nsMacCursor</code> representing the given <code>NSCursor</code>
|
||||
*/
|
||||
+ (nsMacCursor *) cursorWithCursor: (NSCursor *) aCursor;
|
||||
|
||||
/*! @method cursorWithImageNamed:hotSpot:
|
||||
@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
|
||||
by operating system version. eg, Jaguar has a smaller maximum size than Panther.</p>
|
||||
<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
|
||||
@result an autoreleased instance of <code>nsMacCursor</code> that uses the given image and hotspot
|
||||
*/
|
||||
+ (nsMacCursor *) cursorWithImageNamed: (NSString *) aCursorImage hotSpot: (NSPoint) aPoint;
|
||||
|
||||
/*! @method cursorWithFrames:
|
||||
@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.
|
||||
@result an autoreleased instance of <code>nsMacCursor</code> that will animate the given cursor frames
|
||||
*/
|
||||
+ (nsMacCursor *) cursorWithFrames: (NSArray *) aCursorFrames;
|
||||
|
||||
/*! @method cursorWithResources:lastFrame:
|
||||
@abstract Create an animated cursor by specifying a range of <code>CURS</code> resources to load and animate.
|
||||
@discussion Creates a cursor that will animate by cycling through the given range of cursor resource ids. Each
|
||||
resource in the range must be the next frame in the animation.
|
||||
<p>To create a static cursor, simply pass the same resource id for both parameters.</p>
|
||||
<p>The frames are loaded from the compiled version of the resource file nsMacWidget.r.</p>
|
||||
@param aFirstFrame the resource id for the first frame of the animation. Must be 128 or greated
|
||||
@param aLastFrame the resource id for the last frame of the animation. Must be 128 or greater, and greater than
|
||||
or equal to <code>aFirstFrame</code>
|
||||
@result an autoreleased instance of <code>nsMacCursor</code> that will animate the given cursor resources
|
||||
*/
|
||||
+ (nsMacCursor *) cursorWithResources: (int) aFirstFrame lastFrame: (int) aLastFrame;
|
||||
|
||||
/*! @method set
|
||||
@abstract Set the cursor.
|
||||
@discussion Makes this cursor the current cursor. If the cursor is animated, the animation is started.
|
||||
*/
|
||||
- (void) set;
|
||||
|
||||
/*! @method unset
|
||||
@abstract Unset the cursor. The cursor will return to the default (usually the arrow cursor).
|
||||
@discussion Unsets the cursor. If the cursor is animated, the animation is stopped.
|
||||
*/
|
||||
- (void) unset;
|
||||
|
||||
/*! @method isAnimated
|
||||
@abstract Tests whether this cursor is animated.
|
||||
@discussion Use this method to determine whether a cursor is animated
|
||||
@result YES if the cursor is animated (has more than one frame), NO if it is a simple static cursor.
|
||||
*/
|
||||
- (BOOL) isAnimated;
|
||||
@end
|
|
@ -0,0 +1,413 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Camino Cursor Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Andrew Thompson.
|
||||
* Portions created by the Andrew Thompson are Copyright (C) 2004
|
||||
* Andrew Thompson. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#import "nsMacCursor.h"
|
||||
#import "nsMacResources.h"
|
||||
#import "nsDebug.h"
|
||||
|
||||
/*! @category nsMacCursor (PrivateMethods)
|
||||
@abstract Private methods internal to the nsMacCursor class.
|
||||
@discussion <code>nsMacCursor</code> is effectively an abstract class. It does not define complete
|
||||
behaviour in and of itself, the subclasses defined in this file provide the useful implementations.
|
||||
*/
|
||||
@interface nsMacCursor (PrivateMethods)
|
||||
|
||||
/*! @method getNextCursorFrame
|
||||
@abstract get the index of the next cursor frame to display.
|
||||
@discussion Increments and returns the frame counter of an animated cursor.
|
||||
@result The index of the next frame to display in the cursor animation
|
||||
*/
|
||||
- (int) getNextCursorFrame;
|
||||
|
||||
/*! @method numFrames
|
||||
@abstract Query the number of frames in this cursor's animation.
|
||||
@discussion Returns the number of frames in this cursor's animation. Static cursors return 1.
|
||||
*/
|
||||
- (int) numFrames;
|
||||
|
||||
/*! @method createTimer
|
||||
@abstract Create a Timer to use to animate the cursor.
|
||||
@discussion Creates an instance of <code>NSTimer</code> which is used to drive the cursor animation.
|
||||
This method should only be called for cursors that are animated.
|
||||
*/
|
||||
- (void) createTimer;
|
||||
|
||||
/*! @method destroyTimer
|
||||
@abstract Destroy any timer instance associated with this cursor.
|
||||
@discussion Invalidates and releases any <code>NSTimer</code> instance associated with this cursor.
|
||||
*/
|
||||
- (void) destroyTimer;
|
||||
/*! @method destroyTimer
|
||||
@abstract Destroy any timer instance associated with this cursor.
|
||||
@discussion Invalidates and releases any <code>NSTimer</code> instance associated with this cursor.
|
||||
*/
|
||||
|
||||
/*! @method spinCursor:
|
||||
@abstract Method called by animation timer to perform animation.
|
||||
@discussion Called by an animated cursor's associated timer to advance the animation to the next frame.
|
||||
Determines which frame should occur next and sets the cursor to that frame.
|
||||
@param aTimer the timer causing the animation
|
||||
*/
|
||||
- (void) spinCursor: (NSTimer *) aTimer;
|
||||
|
||||
/*! @method setFrame:
|
||||
@abstract Sets the current cursor, using an index to determine which frame in the animation to display.
|
||||
@discussion Sets the current cursor. The frame index determines which frame is shown if the cursor is animated.
|
||||
Frames and numbered from <code>0</code> to <code>-[nsMacCursor numFrames] - 1</code>. A static cursor
|
||||
has a single frame, numbered 0.
|
||||
@param aFrameIndex the index indicating which frame from the animation to display
|
||||
*/
|
||||
- (void) setFrame: (int) aFrameIndex;
|
||||
@end
|
||||
|
||||
/*! @class nsThemeCursor
|
||||
@abstract Implementation of <code>nsMacCursor</code> that uses Carbon Appearance Manager cursors.
|
||||
@discussion Displays a static or animated <code>ThemeCursor</code> using Carbon Appearance Manager functions.
|
||||
Understands how many frames exist in each of the built-in <code>ThemeCursor</code>s.
|
||||
*/
|
||||
@interface nsThemeCursor : nsMacCursor
|
||||
{
|
||||
@private
|
||||
ThemeCursor mCursor;
|
||||
}
|
||||
|
||||
/*! @method initWithThemeCursor:
|
||||
@abstract Create a cursor by specifying a Carbon Apperance Manager <code>ThemeCursor</code> constant.
|
||||
@discussion Creates a cursor representing the given Appearance Manager built in cursor.
|
||||
@param aCursor the <code>ThemeCursor</code> to use
|
||||
@result an instance of <code>nsThemeCursor</code> representing the given <code>ThemeCursor</code>
|
||||
*/
|
||||
- (id) initWithThemeCursor: (ThemeCursor) aCursor;
|
||||
@end
|
||||
|
||||
/*! @class nsCocoaCursor
|
||||
@abstract Implementation of <code>nsMacCursor</code> that uses Cocoa <code>NSCursor</code> instances.
|
||||
@discussion Displays a static or animated cursor, using Cocoa <code>NSCursor</code> instances. These can be either
|
||||
built-in <code>NSCursor</code> instances, or custom <code>NSCursor</code>s created from images.
|
||||
When more than one <code>NSCursor</code> is provided, the cursor will use these as animation frames.
|
||||
*/
|
||||
@interface nsCocoaCursor : nsMacCursor
|
||||
{
|
||||
@private
|
||||
NSArray *mFrames;
|
||||
}
|
||||
|
||||
/*! @method initWithFrames:
|
||||
@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.
|
||||
@result an instance of <code>nsCocoaCursor</code> that will animate the given cursor frames
|
||||
*/
|
||||
- (id) initWithFrames: (NSArray *) aCursorFrames;
|
||||
|
||||
/*! @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
|
||||
@result an instance of <code>nsCocoaCursor</code> representing the given <code>NSCursor</code>
|
||||
*/
|
||||
- (id) initWithCursor: (NSCursor *) aCursor;
|
||||
|
||||
/*! @method initWithImageNamed:hotSpot:
|
||||
@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
|
||||
by operating system version. eg, Jaguar has a smaller maximum size than Panther.</p>
|
||||
<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
|
||||
@result an instance of <code>nsCocoaCursor</code> that uses the given image and hotspot
|
||||
*/
|
||||
- (id) initWithImageNamed: (NSString *) aCursorImage hotSpot: (NSPoint) aPoint;
|
||||
@end
|
||||
|
||||
/*! @class nsResourceCursor
|
||||
@abstract Implementation of <code>nsMacCursor</code> that uses Carbon <code>CURS</code> resources.
|
||||
@discussion Displays a static or animated cursor, using Carbon <code>CURS</code> resources.
|
||||
<p>Animated cursors are produced by cycling through a range of cursor resource ids.</p>
|
||||
<p>The frames are loaded from the compiled version of the resource file nsMacWidget.r.</p>
|
||||
*/
|
||||
@interface nsResourceCursor : nsMacCursor
|
||||
{
|
||||
@private
|
||||
int mFirstFrame;
|
||||
int mLastFrame;
|
||||
}
|
||||
|
||||
/*! @method initWithResources:lastFrame:
|
||||
@abstract Create an animated cursor by specifying a range of <code>CURS</code> resources to load and animate.
|
||||
@discussion Creates a cursor that will animate by cycling through the given range of cursor resource ids. Each
|
||||
resource in the range must be the next frame in the animation.
|
||||
<p>To create a static cursor, simply pass the same resource id for both parameters.</p>
|
||||
<p>The frames are loaded from the compiled version of the resource file nsMacWidget.r.</p>
|
||||
@param aFirstFrame the resource id for the first frame of the animation. Must be 128 or greated
|
||||
@param aLastFrame the resource id for the last frame of the animation. Must be 128 or greater, and greater than
|
||||
or equal to <code>aFirstFrame</code>
|
||||
@result an instance of <code>nsResourceCursor</code> that will animate the given cursor resources
|
||||
*/
|
||||
- (id) initWithFirstFrame: (int) aFirstFrame lastFrame: (int) aLastFrame;
|
||||
@end
|
||||
|
||||
@implementation nsMacCursor
|
||||
|
||||
+ (nsMacCursor *) cursorWithThemeCursor: (ThemeCursor) aCursor
|
||||
{
|
||||
return [[[nsThemeCursor alloc] initWithThemeCursor: aCursor] autorelease];
|
||||
}
|
||||
|
||||
+ (nsMacCursor *) cursorWithResources: (int) aFirstFrame lastFrame: (int) aLastFrame
|
||||
{
|
||||
return [[[nsResourceCursor alloc] initWithFirstFrame: aFirstFrame lastFrame: aLastFrame] autorelease];
|
||||
}
|
||||
|
||||
+ (nsMacCursor *) cursorWithCursor: (NSCursor *) aCursor
|
||||
{
|
||||
return [[[nsCocoaCursor alloc] initWithCursor: aCursor] autorelease];
|
||||
}
|
||||
|
||||
+ (nsMacCursor *) cursorWithImageNamed: (NSString *) aCursorImage hotSpot: (NSPoint) aPoint
|
||||
{
|
||||
return [[[nsCocoaCursor alloc] initWithImageNamed: aCursorImage hotSpot: aPoint] autorelease];
|
||||
}
|
||||
|
||||
+ (nsMacCursor *) cursorWithFrames: (NSArray *) aCursorFrames
|
||||
{
|
||||
return [[[nsCocoaCursor alloc] initWithFrames: aCursorFrames] autorelease];
|
||||
}
|
||||
|
||||
- (void) set
|
||||
{
|
||||
if ( [self isAnimated])
|
||||
{
|
||||
[self createTimer];
|
||||
}
|
||||
//if the cursor isn't animated or the timer creation fails for any reason...
|
||||
if (mTimer == nil)
|
||||
{
|
||||
[self setFrame: 0];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) unset
|
||||
{
|
||||
[self destroyTimer];
|
||||
}
|
||||
|
||||
- (BOOL) isAnimated
|
||||
{
|
||||
return [self numFrames] > 1;
|
||||
}
|
||||
|
||||
- (int) numFrames
|
||||
{
|
||||
//subclasses need to override this to support animation
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (int) getNextCursorFrame
|
||||
{
|
||||
mFrameCounter = (mFrameCounter + 1) % [self numFrames];
|
||||
return mFrameCounter;
|
||||
}
|
||||
|
||||
- (void) createTimer
|
||||
{
|
||||
if ( mTimer == nil)
|
||||
{
|
||||
mTimer = [[NSTimer scheduledTimerWithTimeInterval: 0.25
|
||||
target: self
|
||||
selector: @selector(spinCursor:)
|
||||
userInfo: nil
|
||||
repeats: YES] retain];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) destroyTimer
|
||||
{
|
||||
if ( mTimer != nil)
|
||||
{
|
||||
[mTimer invalidate];
|
||||
[mTimer release];
|
||||
mTimer = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) spinCursor: (NSTimer *) aTimer
|
||||
{
|
||||
if ( [aTimer isValid] )
|
||||
{
|
||||
[self setFrame: [self getNextCursorFrame]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setFrame: (int) aFrameIndex
|
||||
{
|
||||
//subclasses need to do something useful here
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[self destroyTimer];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation nsThemeCursor
|
||||
- (id) initWithThemeCursor: (ThemeCursor) aCursor
|
||||
{
|
||||
self = [super init];
|
||||
//Appearance Manager cursors all fall into the range 0..127. Custom application CURS resources begin at id 128.
|
||||
NS_ASSERTION(mCursor >= 0 && mCursor < 128, "Theme cursors must be in the range 0 <= num < 128");
|
||||
mCursor = aCursor;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) setFrame: (int) aFrameIndex
|
||||
{
|
||||
if ( [self isAnimated] )
|
||||
{
|
||||
//if the cursor is animated try to draw the appropriate frame
|
||||
OSStatus err = ::SetAnimatedThemeCursor(mCursor, aFrameIndex);
|
||||
if ( err != noErr )
|
||||
{
|
||||
//in the event of any kind of problem, just try to show the first frame
|
||||
::SetThemeCursor(mCursor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
::SetThemeCursor(mCursor);
|
||||
}
|
||||
}
|
||||
|
||||
- (int) numFrames
|
||||
{
|
||||
//These don't appear to be documented. Trial and Error...
|
||||
switch (mCursor)
|
||||
{
|
||||
case kThemeWatchCursor:
|
||||
case kThemeSpinningCursor:
|
||||
return 8;
|
||||
case kThemeCountingUpHandCursor:
|
||||
case kThemeCountingDownHandCursor:
|
||||
return 6;
|
||||
case kThemeCountingUpAndDownHandCursor:
|
||||
return 11;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation nsCocoaCursor
|
||||
- (id) initWithFrames: (NSArray *) aCursorFrames
|
||||
{
|
||||
self = [super init];
|
||||
NSEnumerator *it = [aCursorFrames objectEnumerator];
|
||||
NSObject *frame = nil;
|
||||
while ((frame = [it nextObject]) != nil)
|
||||
{
|
||||
NS_ASSERTION([frame isKindOfClass: [NSCursor class]], "Invalid argument: All frames must be of type NSCursor");
|
||||
}
|
||||
mFrames = [aCursorFrames retain];
|
||||
mFrameCounter = 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) initWithCursor: (NSCursor *) aCursor
|
||||
{
|
||||
NSArray *frame = [NSArray arrayWithObjects: aCursor, nil];
|
||||
return [self initWithFrames: frame];
|
||||
}
|
||||
|
||||
- (id) initWithImageNamed: (NSString *) aCursorImage hotSpot: (NSPoint) aPoint
|
||||
{
|
||||
return [self initWithCursor: [[NSCursor alloc] initWithImage: [NSImage imageNamed: aCursorImage] hotSpot: aPoint]];
|
||||
}
|
||||
|
||||
- (void) setFrame: (int) aFrameIndex
|
||||
{
|
||||
[[mFrames objectAtIndex: aFrameIndex] performSelectorOnMainThread: @selector(set) withObject: nil waitUntilDone: NO];
|
||||
}
|
||||
|
||||
- (int) numFrames
|
||||
{
|
||||
return [mFrames count];
|
||||
}
|
||||
|
||||
- (NSString *) description
|
||||
{
|
||||
return [mFrames description];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[mFrames release];
|
||||
[super dealloc];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation nsResourceCursor
|
||||
-(id) initWithFirstFrame: (int) aFirstFrame lastFrame: (int) aLastFrame
|
||||
{
|
||||
self= [super init];
|
||||
//Appearance Manager cursors all fall into the range 0..127. Custom application CURS resources begin at id 128.
|
||||
NS_ASSERTION(aFirstFrame >= 128 && aLastFrame >= 128 && aLastFrame >= aFirstFrame, "Nonsensical frame indicies");
|
||||
mFirstFrame = aFirstFrame;
|
||||
mLastFrame = aLastFrame;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) setFrame: (int) aFrameIndex
|
||||
{
|
||||
nsMacResources::OpenLocalResourceFile();
|
||||
CursHandle cursHandle = ::GetCursor(mFirstFrame + aFrameIndex);
|
||||
NS_ASSERTION(cursHandle, "Can't load cursor, is the resource file installed correctly?");
|
||||
if (cursHandle)
|
||||
{
|
||||
::SetCursor(*cursHandle);
|
||||
}
|
||||
nsMacResources::CloseLocalResourceFile();
|
||||
}
|
||||
|
||||
- (int) numFrames
|
||||
{
|
||||
return (mLastFrame - mFirstFrame) + 1;
|
||||
}
|
||||
@end
|
Загрузка…
Ссылка в новой задаче