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 #include "Platform/Platform.h"
00032
00033
00034 CPImageLoadStatusInitialized = 0;
00035 CPImageLoadStatusLoading = 1;
00036 CPImageLoadStatusCompleted = 2;
00037 CPImageLoadStatusCancelled = 3;
00038 CPImageLoadStatusInvalidData = 4;
00039 CPImageLoadStatusUnexpectedEOF = 5;
00040 CPImageLoadStatusReadError = 6;
00041
00042 CPImageDidLoadNotification = @"CPImageDidLoadNotification";
00043
00044
00045 CPImageNameColorPanel = @"CPImageNameColorPanel";
00046 CPImageNameColorPanelHighlighted = @"CPImageNameColorPanelHighlighted";
00047
00048 var imagesForNames = { },
00049 AppKitImageForNames = { };
00050
00051 AppKitImageForNames[CPImageNameColorPanel] = CGSizeMake(26.0, 29.0);
00052 AppKitImageForNames[CPImageNameColorPanelHighlighted] = CGSizeMake(26.0, 29.0);
00053
00054 function CPImageInBundle(aFilename, aSize, aBundle)
00055 {
00056 if (!aBundle)
00057 aBundle = [CPBundle mainBundle];
00058
00059 if (aSize)
00060 return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename] size:aSize];
00061
00062 return [[CPImage alloc] initWithContentsOfFile:[aBundle pathForResource:aFilename]];
00063 }
00064
00065 function CPAppKitImage(aFilename, aSize)
00066 {
00067 return CPImageInBundle(aFilename, aSize, [CPBundle bundleForClass:[CPView class]]);
00068 }
00069
00091 @implementation CPImage : CPObject
00092 {
00093 CGSize _size;
00094 CPString _filename;
00095 CPString _name;
00096
00097 id _delegate;
00098 unsigned _loadStatus;
00099
00100 Image _image;
00101 }
00102
00103 - (id)init
00104 {
00105 return [self initByReferencingFile:@"" size:CGSizeMake(-1, -1)];
00106 }
00107
00116 - (id)initByReferencingFile:(CPString)aFilename size:(CGSize)aSize
00117 {
00118 self = [super init];
00119
00120 if (self)
00121 {
00122 _size = CPSizeCreateCopy(aSize);
00123 _filename = aFilename;
00124 _loadStatus = CPImageLoadStatusInitialized;
00125 }
00126
00127 return self;
00128 }
00129
00136 - (id)initWithContentsOfFile:(CPString)aFilename size:(CGSize)aSize
00137 {
00138 self = [self initByReferencingFile:aFilename size:aSize];
00139
00140 if (self)
00141 [self load];
00142
00143 return self;
00144 }
00145
00152 - (id)initWithContentsOfFile:(CPString)aFilename
00153 {
00154 self = [self initByReferencingFile:aFilename size:CGSizeMake(-1, -1)];
00155
00156 if (self)
00157 [self load];
00158
00159 return self;
00160 }
00161
00165 - (CPString)filename
00166 {
00167 return _filename;
00168 }
00169
00174 - (void)setSize:(CGSize)aSize
00175 {
00176 _size = CGSizeMakeCopy(aSize);
00177 }
00178
00182 - (CGSize)size
00183 {
00184 return _size;
00185 }
00186
00187 + (id)imageNamed:(CPString)aName
00188 {
00189 var image = imagesForNames[aName];
00190
00191 if (image)
00192 return image;
00193
00194 var imageOrSize = AppKitImageForNames[aName];
00195
00196 if (!imageOrSize.isa)
00197 {
00198 imageOrSize = CPAppKitImage("CPImage/" + aName + ".png", imageOrSize);
00199
00200 [imageOrSize setName:aName];
00201
00202 AppKitImageForNames[aName] = imageOrSize;
00203 }
00204
00205 return imageOrSize;
00206 }
00207
00208 - (void)setName:(CPString)aName
00209 {
00210 if (_name === aName)
00211 return;
00212
00213 if (imagesForNames[aName] === self)
00214 imagesForNames[aName] = nil;
00215
00216 _name = aName;
00217
00218 imagesForNames[aName] = self;
00219 }
00220
00221 - (CPString)name
00222 {
00223 return _name;
00224 }
00225
00230 - (void)setDelegate:(id)aDelegate
00231 {
00232 _delegate = aDelegate;
00233 }
00234
00238 - (id)delegate
00239 {
00240 return _delegate;
00241 }
00242
00246 - (unsigned)loadStatus
00247 {
00248 return _loadStatus;
00249 }
00250
00257 - (void)load
00258 {
00259 if (_loadStatus == CPImageLoadStatusLoading || _loadStatus == CPImageLoadStatusCompleted)
00260 return;
00261
00262 _loadStatus = CPImageLoadStatusLoading;
00263
00264 #if PLATFORM(DOM)
00265 _image = new Image();
00266
00267 var isSynchronous = YES;
00268
00269
00270 _image.onload = function ()
00271 {
00272 if (isSynchronous)
00273 window.setTimeout(function() { [self _imageDidLoad]; }, 0);
00274 else
00275 {
00276 [self _imageDidLoad];
00277 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00278 }
00279 [self _derefFromImage];
00280 }
00281
00282 _image.onerror = function ()
00283 {
00284 if (isSynchronous)
00285 window.setTimeout(function() { [self _imageDidError]; }, 0);
00286 else
00287 {
00288 [self _imageDidError];
00289 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00290 }
00291 [self _derefFromImage];
00292 }
00293
00294 _image.onabort = function ()
00295 {
00296 if (isSynchronous)
00297 window.setTimeout(function() { [self _imageDidAbort]; }, 0);
00298 else
00299 {
00300 [self _imageDidAbort];
00301 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
00302 }
00303 [self _derefFromImage];
00304 }
00305
00306 _image.src = _filename;
00307
00308
00309
00310 window.setTimeout(function() { isSynchronous = NO; }, 0);
00311 #endif
00312 }
00313
00314 - (BOOL)isThreePartImage
00315 {
00316 return NO;
00317 }
00318
00319 - (BOOL)isNinePartImage
00320 {
00321 return NO;
00322 }
00323
00324
00325 - (void)_derefFromImage
00326 {
00327 _image.onload = null;
00328 _image.onerror = null;
00329 _image.onabort = null;
00330 }
00331
00332
00333 - (void)_imageDidLoad
00334 {
00335 _loadStatus = CPImageLoadStatusCompleted;
00336
00337
00338 if (!_size || (_size.width == -1 && _size.height == -1))
00339 _size = CGSizeMake(_image.width, _image.height);
00340
00341 [[CPNotificationCenter defaultCenter]
00342 postNotificationName:CPImageDidLoadNotification
00343 object:self];
00344
00345 if ([_delegate respondsToSelector:@selector(imageDidLoad:)])
00346 [_delegate imageDidLoad:self];
00347 }
00348
00349
00350 - (void)_imageDidError
00351 {
00352 _loadStatus = CPImageLoadStatusReadError;
00353
00354 if ([_delegate respondsToSelector:@selector(imageDidError:)])
00355 [_delegate imageDidError:self];
00356 }
00357
00358
00359 - (void)_imageDidAbort
00360 {
00361 _loadStatus = CPImageLoadStatusCancelled;
00362
00363 if ([_delegate respondsToSelector:@selector(imageDidAbort:)])
00364 [_delegate imageDidAbort:self];
00365 }
00366
00367 @end
00368
00369 @implementation CPImage (CPCoding)
00370
00376 - (id)initWithCoder:(CPCoder)aCoder
00377 {
00378 return [self initWithContentsOfFile:[aCoder decodeObjectForKey:@"CPFilename"] size:[aCoder decodeSizeForKey:@"CPSize"]];
00379 }
00380
00385 - (void)encodeWithCoder:(CPCoder)aCoder
00386 {
00387 [aCoder encodeObject:_filename forKey:@"CPFilename"];
00388 [aCoder encodeSize:_size forKey:@"CPSize"];
00389 }
00390
00391 @end
00392
00393 @implementation CPThreePartImage : CPObject
00394 {
00395 CPArray _imageSlices;
00396 BOOL _isVertical;
00397 }
00398
00399 - (id)initWithImageSlices:(CPArray)imageSlices isVertical:(BOOL)isVertical
00400 {
00401 self = [super init];
00402
00403 if (self)
00404 {
00405 _imageSlices = imageSlices;
00406 _isVertical = isVertical;
00407 }
00408
00409 return self;
00410 }
00411
00412 - (CPString)filename
00413 {
00414 return @"";
00415 }
00416
00417 - (CPArray)imageSlices
00418 {
00419 return _imageSlices;
00420 }
00421
00422 - (BOOL)isVertical
00423 {
00424 return _isVertical;
00425 }
00426
00427 - (BOOL)isThreePartImage
00428 {
00429 return YES;
00430 }
00431
00432 - (BOOL)isNinePartImage
00433 {
00434 return NO;
00435 }
00436
00437 @end
00438
00439 var CPThreePartImageImageSlicesKey = @"CPThreePartImageImageSlicesKey",
00440 CPThreePartImageIsVerticalKey = @"CPThreePartImageIsVerticalKey";
00441
00442 @implementation CPThreePartImage (CPCoding)
00443
00444 - (id)initWithCoder:(CPCoder)aCoder
00445 {
00446 self = [super init];
00447
00448 if (self)
00449 {
00450 _imageSlices = [aCoder decodeObjectForKey:CPThreePartImageImageSlicesKey];
00451 _isVertical = [aCoder decodeBoolForKey:CPThreePartImageIsVerticalKey];
00452 }
00453
00454 return self;
00455 }
00456
00457 - (void)encodeWithCoder:(CPCoder)aCoder
00458 {
00459 [aCoder encodeObject:_imageSlices forKey:CPThreePartImageImageSlicesKey];
00460 [aCoder encodeBool:_isVertical forKey:CPThreePartImageIsVerticalKey];
00461 }
00462
00463 @end
00464
00465
00466 @implementation CPNinePartImage : CPObject
00467 {
00468 CPArray _imageSlices;
00469 }
00470
00471 - (id)initWithImageSlices:(CPArray)imageSlices
00472 {
00473 self = [super init];
00474
00475 if (self)
00476 _imageSlices = imageSlices;
00477
00478 return self;
00479 }
00480
00481 - (CPString)filename
00482 {
00483 return @"";
00484 }
00485
00486 - (CPArray)imageSlices
00487 {
00488 return _imageSlices;
00489 }
00490
00491 - (BOOL)isThreePartImage
00492 {
00493 return NO;
00494 }
00495
00496 - (BOOL)isNinePartImage
00497 {
00498 return YES;
00499 }
00500
00501 @end
00502
00503 var CPNinePartImageImageSlicesKey = @"CPNinePartImageImageSlicesKey";
00504
00505 @implementation CPNinePartImage (CPCoding)
00506
00507 - (id)initWithCoder:(CPCoder)aCoder
00508 {
00509 self = [super init];
00510
00511 if (self)
00512 _imageSlices = [aCoder decodeObjectForKey:CPNinePartImageImageSlicesKey];
00513
00514 return self;
00515 }
00516
00517 - (void)encodeWithCoder:(CPCoder)aCoder
00518 {
00519 [aCoder encodeObject:_imageSlices forKey:CPNinePartImageImageSlicesKey];
00520 }
00521
00522 @end