00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import <Foundation/CPBundle.j>
00024 @import <Foundation/CPNotificationCenter.j>
00025 @import <Foundation/CPObject.j>
00026 @import <Foundation/CPRunLoop.j>
00027 @import <Foundation/CPString.j>
00028
00029 @import "CPGeometry.j"
00030
00031 CPImageLoadStatusInitialized = 0;
00032 CPImageLoadStatusLoading = 1;
00033 CPImageLoadStatusCompleted = 2;
00034 CPImageLoadStatusCancelled = 3;
00035 CPImageLoadStatusInvalidData = 4;
00036 CPImageLoadStatusUnexpectedEOF = 5;
00037 CPImageLoadStatusReadError = 6;
00038
00039 CPImageDidLoadNotification = @"CPImageDidLoadNotification";
00040
00041 function CPImageInBundle(aFilename, aSize, aBundle)
00042 {
00043 if (!aBundle)
00044 aBundle = [CPBundle mainBundle];
00045
00046 if (aSize)
00047 return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename] size:aSize];
00048
00049 return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename]];
00050 }
00051
00052 @implementation CPBundle (CPImageAdditions)
00053
00054 - (CPString)pathForResource:(CPString)aFilename
00055 {
00056 return [self resourcePath] + '/' + aFilename;
00057 }
00058
00059 @end
00060
00082 @implementation CPImage : CPObject
00083 {
00084 CGSize _size;
00085 CPString _filename;
00086
00087 id _delegate;
00088 unsigned _loadStatus;
00089
00090 Image _image;
00091 }
00092
00101 - (CPImage)initByReferencingFile:(CPString)aFilename size:(CGSize)aSize
00102 {
00103 self = [super init];
00104
00105 if (self)
00106 {
00107 _size = CPSizeCreateCopy(aSize);
00108 _filename = aFilename;
00109 _loadStatus = CPImageLoadStatusInitialized;
00110 }
00111
00112 return self;
00113 }
00114
00121 - (CPImage)initWithContentsOfFile:(CPString)aFilename size:(CGSize)aSize
00122 {
00123 self = [self initByReferencingFile:aFilename size:aSize];
00124
00125 if (self)
00126 [self load];
00127
00128 return self;
00129 }
00130
00137 - (CPImage)initWithContentsOfFile:(CPString)aFilename
00138 {
00139 self = [self initByReferencingFile:aFilename size: CGSizeMake(-1, -1)];
00140
00141 if (self)
00142 [self load];
00143
00144 return self;
00145 }
00146
00150 - (CPString)filename
00151 {
00152 return _filename;
00153 }
00154
00159 - (void)setSize:(CGSize)aSize
00160 {
00161 _size = CGSizeMakeCopy(aSize);
00162 }
00163
00167 - (CGSize)size
00168 {
00169 return _size;
00170 }
00171
00176 - (void)setDelegate:(id)aDelegate
00177 {
00178 _delegate = aDelegate;
00179 }
00180
00184 - (id)delegate
00185 {
00186 return _delegate;
00187 }
00188
00192 - (BOOL)loadStatus
00193 {
00194 return _loadStatus;
00195 }
00196
00203 - (void)load
00204 {
00205 if (_loadStatus == CPImageLoadStatusLoading || _loadStatus == CPImageLoadStatusCompleted)
00206 return;
00207
00208 _loadStatus = CPImageLoadStatusLoading;
00209
00210 _image = new Image();
00211
00212 var isSynchronous = YES;
00213
00214
00215 _image.onload = function ()
00216 {
00217 if (isSynchronous)
00218 window.setTimeout(function() { [self _imageDidLoad]; }, 0);
00219 else
00220 {
00221 [self _imageDidLoad];
00222 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00223 }
00224 [self _derefFromImage];
00225 }
00226
00227 _image.onerror = function ()
00228 {
00229 if (isSynchronous)
00230 window.setTimeout(function() { [self _imageDidError]; }, 0);
00231 else
00232 {
00233 [self _imageDidError];
00234 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00235 }
00236 [self _derefFromImage];
00237 }
00238
00239 _image.onabort = function ()
00240 {
00241 if (isSynchronous)
00242 window.setTimeout(function() { [self _imageDidAbort]; }, 0);
00243 else
00244 {
00245 [self _imageDidAbort];
00246 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00247 }
00248 [self _derefFromImage];
00249 }
00250
00251 _image.src = _filename;
00252
00253 isSynchronous = NO;
00254 }
00255
00256 - (BOOL)isThreePartImage
00257 {
00258 return NO;
00259 }
00260
00261 - (BOOL)isNinePartImage
00262 {
00263 return NO;
00264 }
00265
00266
00267 - (void)_derefFromImage
00268 {
00269 _image.onload = null;
00270 _image.onerror = null;
00271 _image.onabort = null;
00272 }
00273
00274
00275 - (void)_imageDidLoad
00276 {
00277 _loadStatus = CPImageLoadStatusCompleted;
00278
00279
00280 if (!_size || (_size.width == -1 && _size.height == -1))
00281 _size = CGSizeMake(_image.width, _image.height);
00282
00283 [[CPNotificationCenter defaultCenter]
00284 postNotificationName:CPImageDidLoadNotification
00285 object:self];
00286
00287 if ([_delegate respondsToSelector:@selector(imageDidLoad:)])
00288 [_delegate imageDidLoad:self];
00289 }
00290
00291
00292 - (void)_imageDidError
00293 {
00294 _loadStatus = CPImageLoadStatusReadError;
00295
00296 if ([_delegate respondsToSelector:@selector(imageDidError:)])
00297 [_delegate imageDidError:self];
00298 }
00299
00300
00301 - (void)_imageDidAbort
00302 {
00303 _loadStatus = CPImageLoadStatusCancelled;
00304
00305 if ([_delegate respondsToSelector:@selector(imageDidAbort:)])
00306 [_delegate imageDidAbort:self];
00307 }
00308
00309 @end
00310
00311 @implementation CPImage (CPCoding)
00312
00318 - (id)initWithCoder:(CPCoder)aCoder
00319 {
00320 return [self initWithContentsOfFile:[aCoder decodeObjectForKey:@"CPFilename"] size:[aCoder decodeSizeForKey:@"CPSize"]];
00321 }
00322
00327 - (void)encodeWithCoder:(CPCoder)aCoder
00328 {
00329 [aCoder encodeObject:_filename forKey:@"CPFilename"];
00330 [aCoder encodeSize:_size forKey:@"CPSize"];
00331 }
00332
00333 @end
00334
00335 @implementation CPThreePartImage : CPObject
00336 {
00337 CPArray _imageSlices;
00338 BOOL _isVertical;
00339 }
00340
00341 - (id)initWithImageSlices:(CPArray)imageSlices isVertical:(BOOL)isVertical
00342 {
00343 self = [super init];
00344
00345 if (self)
00346 {
00347 _imageSlices = imageSlices;
00348 _isVertical = isVertical;
00349 }
00350
00351 return self;
00352 }
00353
00354 - (CPString)filename
00355 {
00356 return @"";
00357 }
00358
00359 - (CPArray)imageSlices
00360 {
00361 return _imageSlices;
00362 }
00363
00364 - (BOOL)isVertical
00365 {
00366 return _isVertical;
00367 }
00368
00369 - (BOOL)isThreePartImage
00370 {
00371 return YES;
00372 }
00373
00374 - (BOOL)isNinePartImage
00375 {
00376 return NO;
00377 }
00378
00379 @end
00380
00381 var CPThreePartImageImageSlicesKey = @"CPThreePartImageImageSlicesKey",
00382 CPThreePartImageIsVerticalKey = @"CPThreePartImageIsVerticalKey";
00383
00384 @implementation CPThreePartImage (CPCoding)
00385
00386 - (id)initWithCoder:(CPCoder)aCoder
00387 {
00388 self = [super init];
00389
00390 if (self)
00391 {
00392 _imageSlices = [aCoder decodeObjectForKey:CPThreePartImageImageSlicesKey];
00393 _isVertical = [aCoder decodeBoolForKey:CPThreePartImageIsVerticalKey];
00394 }
00395
00396 return self;
00397 }
00398
00399 - (void)encodeWithCoder:(CPCoder)aCoder
00400 {
00401 [aCoder encodeObject:_imageSlices forKey:CPThreePartImageImageSlicesKey];
00402 [aCoder encodeBool:_isVertical forKey:CPThreePartImageIsVerticalKey];
00403 }
00404
00405 @end
00406
00407
00408 @implementation CPNinePartImage : CPObject
00409 {
00410 CPArray _imageSlices;
00411 }
00412
00413 - (id)initWithImageSlices:(CPArray)imageSlices
00414 {
00415 self = [super init];
00416
00417 if (self)
00418 _imageSlices = imageSlices;
00419
00420 return self;
00421 }
00422
00423 - (CPString)filename
00424 {
00425 return @"";
00426 }
00427
00428 - (CPArray)imageSlices
00429 {
00430 return _imageSlices;
00431 }
00432
00433 - (BOOL)isThreePartImage
00434 {
00435 return NO;
00436 }
00437
00438 - (BOOL)isNinePartImage
00439 {
00440 return YES;
00441 }
00442
00443 @end
00444
00445 var CPNinePartImageImageSlicesKey = @"CPNinePartImageImageSlicesKey";
00446
00447 @implementation CPNinePartImage (CPCoding)
00448
00449 - (id)initWithCoder:(CPCoder)aCoder
00450 {
00451 self = [super init];
00452
00453 if (self)
00454 _imageSlices = [aCoder decodeObjectForKey:CPNinePartImageImageSlicesKey];
00455
00456 return self;
00457 }
00458
00459 - (void)encodeWithCoder:(CPCoder)aCoder
00460 {
00461 [aCoder encodeObject:_imageSlices forKey:CPNinePartImageImageSlicesKey];
00462 }
00463
00464 @end