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/CPNotificationCenter.j>
00024
00025 @import "CPControl.j"
00026 @import "CPImage.j"
00027 @import "CPShadowView.j"
00028
00029 #include "Platform/Platform.h"
00030 #include "Platform/DOM/CPDOMDisplayServer.h"
00031
00032 #include "CoreGraphics/CGGeometry.h"
00033
00034
00035
00036
00037
00038
00039 CPScaleProportionally = 0;
00040
00041
00042
00043
00044 CPScaleToFit = 1;
00045
00046
00047
00048
00049 CPScaleNone = 2;
00050
00051
00052 var CPImageViewShadowBackgroundColor = nil;
00053
00054 var LEFT_SHADOW_INSET = 3.0,
00055 RIGHT_SHADOW_INSET = 3.0,
00056 TOP_SHADOW_INSET = 3.0,
00057 BOTTOM_SHADOW_INSET = 5.0,
00058 VERTICAL_SHADOW_INSET = TOP_SHADOW_INSET + BOTTOM_SHADOW_INSET,
00059 HORIZONTAL_SHADOW_INSET = LEFT_SHADOW_INSET + RIGHT_SHADOW_INSET;
00060
00065 @implementation CPImageView : CPControl
00066 {
00067 CPImage _image;
00068 DOMElement _DOMImageElement;
00069
00070 CPImageScaling _imageScaling;
00071
00072 BOOL _hasShadow;
00073 CPView _shadowView;
00074
00075 CGRect _imageRect;
00076 }
00077
00078 - (id)initWithFrame:(CGRect)aFrame
00079 {
00080 self = [super initWithFrame:aFrame];
00081
00082 if (self)
00083 {
00084 #if PLATFORM(DOM)
00085 _DOMImageElement = document.createElement("img");
00086 _DOMImageElement.style.position = "absolute";
00087 _DOMImageElement.style.left = "0px";
00088 _DOMImageElement.style.top = "0px";
00089
00090 CPDOMDisplayServerAppendChild(_DOMElement, _DOMImageElement);
00091
00092 _DOMImageElement.style.visibility = "hidden";
00093 #endif
00094 }
00095
00096 return self;
00097 }
00098
00102 - (CPImage)image
00103 {
00104 return _image;
00105 }
00106
00111 - (void)setImage:(CPImage)anImage
00112 {
00113 if (_image == anImage)
00114 return;
00115
00116 var center = [CPNotificationCenter defaultCenter];
00117
00118 if (_image)
00119 [center removeObserver:self name:CPImageDidLoadNotification object:_image];
00120
00121 _image = anImage;
00122 _DOMImageElement.src = [anImage filename];
00123
00124 var size = [_image size];
00125
00126 if (size && size.width == -1 && size.height == -1)
00127 {
00128 [center addObserver:self selector:@selector(imageDidLoad:) name:CPImageDidLoadNotification object:_image];
00129
00130 _DOMImageElement.width = 0;
00131 _DOMImageElement.height = 0;
00132
00133 [_shadowView setHidden:YES];
00134 }
00135 else
00136 {
00137 [self hideOrDisplayContents];
00138 [self tile];
00139 }
00140 }
00141
00142 - (void)imageDidLoad:(CPNotification)aNotification
00143 {
00144 [self hideOrDisplayContents];
00145 [self tile];
00146 }
00147
00152 - (BOOL)hasShadow
00153 {
00154 return _hasShadow;
00155 }
00156
00161 - (void)setHasShadow:(BOOL)shouldHaveShadow
00162 {
00163 if (_hasShadow == shouldHaveShadow)
00164 return;
00165
00166 _hasShadow = shouldHaveShadow;
00167
00168 if (_hasShadow)
00169 {
00170 _shadowView = [[CPShadowView alloc] initWithFrame:[self bounds]];
00171
00172 [self addSubview:_shadowView];
00173
00174 [self tile];
00175 }
00176 else
00177 {
00178 [_shadowView removeFromSuperview];
00179
00180 _shadowView = nil;
00181 }
00182
00183 [self hideOrDisplayContents];
00184 }
00185
00191 - (void)setImageScaling:(CPImageScaling)anImageScaling
00192 {
00193 if (_imageScaling == anImageScaling)
00194 return;
00195
00196 _imageScaling = anImageScaling;
00197
00198 if (_imageScaling == CPScaleToFit)
00199 {
00200 CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, 0.0, 0.0);
00201 }
00202
00203 [self tile];
00204 }
00205
00210 - (CPImageScaling)imageScaling
00211 {
00212 return _imageScaling;
00213 }
00214
00215 - (void)setFrameSize:(CGSize)aSize
00216 {
00217 [super setFrameSize:aSize];
00218
00219 [self tile];
00220 }
00221
00225 - (void)hideOrDisplayContents
00226 {
00227 if (!_image)
00228 {
00229 _DOMImageElement.style.visibility = "hidden";
00230 [_shadowView setHidden:YES];
00231 }
00232 else
00233 {
00234 _DOMImageElement.style.visibility = "visible";
00235 [_shadowView setHidden:NO];
00236 }
00237 }
00238
00242 - (CGRect)imageRect
00243 {
00244 return _imageRect;
00245 }
00246
00250 - (void)tile
00251 {
00252 if (!_image)
00253 return;
00254
00255 var bounds = [self bounds],
00256 x = 0.0,
00257 y = 0.0,
00258 insetWidth = (_hasShadow ? HORIZONTAL_SHADOW_INSET : 0.0),
00259 insetHeight = (_hasShadow ? VERTICAL_SHADOW_INSET : 0.0),
00260 boundsWidth = _CGRectGetWidth(bounds),
00261 boundsHeight = _CGRectGetHeight(bounds),
00262 width = boundsWidth - insetWidth,
00263 height = boundsHeight - insetHeight;
00264
00265 if (_imageScaling == CPScaleToFit)
00266 {
00267 _DOMImageElement.width = ROUND(width);
00268 _DOMImageElement.height = ROUND(height);
00269 }
00270 else
00271 {
00272 var size = [_image size];
00273
00274 if (size.width == -1 && size.height == -1)
00275 return;
00276
00277 if (_imageScaling == CPScaleProportionally)
00278 {
00279
00280
00281 if (width >= size.width && height >= size.height)
00282 {
00283 width = size.width;
00284 height = size.height;
00285 }
00286 else
00287 {
00288 var imageRatio = size.width / size.height,
00289 viewRatio = width / height;
00290
00291 if (viewRatio > imageRatio)
00292 width = height * imageRatio;
00293 else
00294 height = width / imageRatio;
00295 }
00296
00297 _DOMImageElement.width = ROUND(width);
00298 _DOMImageElement.height = ROUND(height);
00299 }
00300 else
00301 {
00302 width = size.width;
00303 height = size.height;
00304 }
00305
00306 if (_imageScaling == CPScaleNone)
00307 {
00308 _DOMImageElement.width = ROUND(size.width);
00309 _DOMImageElement.height = ROUND(size.height);
00310 }
00311
00312 var x = (boundsWidth - width) / 2.0,
00313 y = (boundsHeight - height) / 2.0;
00314
00315 CPDOMDisplayServerSetStyleLeftTop(_DOMImageElement, NULL, x, y);
00316 }
00317
00318 _imageRect = _CGRectMake(x, y, width, height);
00319
00320 if (_hasShadow)
00321 [_shadowView setFrame:_CGRectMake(x - LEFT_SHADOW_INSET, y - TOP_SHADOW_INSET, width + insetWidth, height + insetHeight)];
00322 }
00323
00324 @end
00325
00326 var CPImageViewImageKey = @"CPImageViewImageKey",
00327 CPImageViewImageScalingKey = @"CPImageViewImageScalingKey",
00328 CPImageViewHasShadowKey = @"CPImageViewHasShadowKey";
00329
00330 @implementation CPImageView (CPCoding)
00331
00337 - (id)initWithCoder:(CPCoder)aCoder
00338 {
00339 self = [super initWithCoder:aCoder];
00340
00341 if (self)
00342 {
00343 _DOMImageElement = document.createElement("img");
00344 _DOMImageElement.style.position = "absolute";
00345 _DOMImageElement.style.left = "0px";
00346 _DOMImageElement.style.top = "0px";
00347
00348 _DOMElement.appendChild(_DOMImageElement);
00349 _DOMImageElement.style.visibility = "hidden";
00350
00351 [self setImage:[aCoder decodeObjectForKey:CPImageViewImageKey]];
00352
00353 [self setImageScaling:[aCoder decodeIntForKey:CPImageViewImageScalingKey]];
00354 [self setHasShadow:[aCoder decodeBoolForKey:CPImageViewHasShadowKey]];
00355
00356 [self tile];
00357 }
00358
00359 return self;
00360 }
00361
00367 - (void)encodeWithCoder:(CPCoder)aCoder
00368 {
00369
00370
00371 if (_shadowView)
00372 {
00373 var actualSubviews = _subviews;
00374
00375 _subviews = [_subviews copy];
00376 [_subviews removeObjectIdenticalTo:_shadowView];
00377 }
00378
00379 [super encodeWithCoder:aCoder];
00380
00381 if (_shadowView)
00382 _subviews = actualSubviews;
00383
00384 [aCoder encodeObject:_image forKey:CPImageViewImageKey];
00385
00386 [aCoder encodeInt:_imageScaling forKey:CPImageViewImageScalingKey];
00387 [aCoder encodeBool:_hasShadow forKey:CPImageViewHasShadowKey];
00388 }
00389
00390 @end