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/CPArray.j>
00024 @import <Foundation/CPObjJRuntime.j>
00025
00026 @import "CGAffineTransform.j"
00027 @import "CGGeometry.j"
00028
00029 @import "CPColor.j"
00030 @import "CPDOMDisplayServer.j"
00031 @import "CPGeometry.j"
00032 @import "CPResponder.j"
00033 @import "CPGraphicsContext.j"
00034
00035
00036 #include "Platform/Platform.h"
00037 #include "CoreGraphics/CGAffineTransform.h"
00038 #include "CoreGraphics/CGGeometry.h"
00039 #include "Platform/DOM/CPDOMDisplayServer.h"
00040
00041
00042
00043
00044
00045
00046 CPViewNotSizable = 0;
00047
00048
00049
00050
00051
00052 CPViewMinXMargin = 1;
00053
00054
00055
00056
00057
00058 CPViewWidthSizable = 2;
00059
00060
00061
00062
00063
00064 CPViewMaxXMargin = 4;
00065
00066
00067
00068
00069
00070 CPViewMinYMargin = 8;
00071
00072
00073
00074
00075
00076 CPViewHeightSizable = 16;
00077
00078
00079
00080
00081
00082 CPViewMaxYMargin = 32;
00083
00084 CPViewBoundsDidChangeNotification = @"CPViewBoundsDidChangeNotification";
00085 CPViewFrameDidChangeNotification = @"CPViewFrameDidChangeNotification";
00086
00087 var _DOMOriginUpdateMask = 1 << 0,
00088 _DOMSizeUpdateMask = 1 << 1;
00089
00090 var _CPViewNotificationCenter = nil;
00091
00092 #if PLATFORM(DOM)
00093 var DOMElementPrototype = nil,
00094
00095 BackgroundTrivialColor = 0,
00096 BackgroundVerticalThreePartImage = 1,
00097 BackgroundHorizontalThreePartImage = 2,
00098 BackgroundNinePartImage = 3,
00099
00100 CustomDrawRectViews = {};
00101 #endif
00102
00118 @implementation CPView : CPResponder
00119 {
00120 CPWindow _window;
00121
00122 CPView _superview;
00123 CPArray _subviews;
00124
00125 CPGraphicsContext _graphicsContext;
00126
00127 int _tag;
00128
00129 CGRect _frame;
00130 CGRect _bounds;
00131 CGAffineTransform _boundsTransform;
00132 CGAffineTransform _inverseBoundsTransform;
00133
00134 CPArray _registeredDraggedTypes;
00135
00136 BOOL _isHidden;
00137 BOOL _hitTests;
00138
00139 BOOL _postsFrameChangedNotifications;
00140 BOOL _postsBoundsChangedNotifications;
00141 BOOL _inhibitFrameAndBoundsChangedNotifications;
00142
00143 CPString _displayHash;
00144
00145 #if PLATFORM(DOM)
00146 DOMElement _DOMElement;
00147 DOMElement _DOMContentsElement;
00148
00149 CPArray _DOMImageParts;
00150 CPArray _DOMImageSizes;
00151
00152 unsigned _backgroundType;
00153 #endif
00154
00155 CGRect _dirtyRect;
00156
00157 float _opacity;
00158 CPColor _backgroundColor;
00159
00160 BOOL _autoresizesSubviews;
00161 unsigned _autoresizingMask;
00162
00163 CALayer _layer;
00164 BOOL _wantsLayer;
00165
00166
00167 BOOL _isInFullScreenMode;
00168
00169 _CPViewFullScreenModeState _fullScreenModeState;
00170 }
00171
00172
00173
00174
00175
00176 + (void)initialize
00177 {
00178 if (self != [CPView class])
00179 return;
00180
00181 #if PLATFORM(DOM)
00182 DOMElementPrototype = document.createElement("div");
00183
00184 var style = DOMElementPrototype.style;
00185
00186 style.overflow = "hidden";
00187 style.position = "absolute";
00188 style.visibility = "visible";
00189 style.zIndex = 0;
00190 #endif
00191
00192 _CPViewNotificationCenter = [CPNotificationCenter defaultCenter];
00193 }
00194
00195 - (id)init
00196 {
00197 return [self initWithFrame:CGRectMakeZero()];
00198 }
00199
00204 - (id)initWithFrame:(CGRect)aFrame
00205 {
00206 self = [super init];
00207
00208 if (self)
00209 {
00210 var width = _CGRectGetWidth(aFrame),
00211 height = _CGRectGetHeight(aFrame);
00212
00213 _subviews = [];
00214
00215 _tag = -1;
00216
00217 _frame = _CGRectMakeCopy(aFrame);
00218 _bounds = _CGRectMake(0.0, 0.0, width, height);
00219
00220 _registeredDraggedTypes = [];
00221
00222 _autoresizingMask = CPViewNotSizable;
00223 _autoresizesSubviews = YES;
00224
00225 _opacity = 1.0;
00226 _isHidden = NO;
00227 _hitTests = YES;
00228
00229 _displayHash = [self hash];
00230
00231 #if PLATFORM(DOM)
00232 _DOMElement = DOMElementPrototype.cloneNode(false);
00233
00234 CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, _CGRectGetMinX(aFrame), _CGRectGetMinY(aFrame));
00235 CPDOMDisplayServerSetStyleSize(_DOMElement, width, height);
00236
00237 _DOMImageParts = [];
00238 _DOMImageSizes = [];
00239 #endif
00240 }
00241
00242 return self;
00243 }
00244
00249 - (CPView)superview
00250 {
00251 return _superview;
00252 }
00253
00258 - (CPArray)subviews
00259 {
00260 return _subviews;
00261 }
00262
00266 - (CPWindow)window
00267 {
00268 return _window;
00269 }
00270
00275 - (void)addSubview:(CPView)aSubview
00276 {
00277 [self _insertSubview:aSubview atIndex:CPNotFound];
00278 }
00279
00286 - (void)addSubview:(CPView)aSubview positioned:(CPWindowOrderingMode)anOrderingMode relativeTo:(CPView)anotherView
00287 {
00288 var index = anotherView ? [_subviews indexOfObjectIdenticalTo:anotherView] : CPNotFound;
00289
00290
00291 if (index === CPNotFound)
00292 index = (anOrderingMode === CPWindowAbove) ? [_subviews count] : 0;
00293
00294
00295 else if (anOrderingMode === CPWindowAbove)
00296 ++index;
00297
00298 [self _insertSubview:aSubview atIndex:index];
00299 }
00300
00301
00302 - (void)_insertSubview:(CPView)aSubview atIndex:(int)anIndex
00303 {
00304
00305 var count = _subviews.length;
00306
00307
00308 if (aSubview._superview == self)
00309 {
00310 var index = [_subviews indexOfObjectIdenticalTo:aSubview];
00311
00312
00313 if (index === anIndex || index === count - 1 && anIndex === count)
00314 return;
00315
00316 [_subviews removeObjectAtIndex:index];
00317
00318 #if PLATFORM(DOM)
00319 CPDOMDisplayServerRemoveChild(_DOMElement, aSubview._DOMElement);
00320 #endif
00321
00322 if (anIndex > index)
00323 --anIndex;
00324
00325
00326 --count;
00327 }
00328 else
00329 {
00330
00331 [aSubview removeFromSuperview];
00332
00333
00334 [aSubview _setWindow:_window];
00335
00336
00337 [aSubview viewWillMoveToSuperview:self];
00338
00339
00340 aSubview._superview = self;
00341 }
00342
00343 if (anIndex === CPNotFound || anIndex >= count)
00344 {
00345 _subviews.push(aSubview);
00346
00347 #if PLATFORM(DOM)
00348
00349 CPDOMDisplayServerAppendChild(_DOMElement, aSubview._DOMElement);
00350 #endif
00351 }
00352 else
00353 {
00354 _subviews.splice(anIndex, 0, aSubview);
00355
00356 #if PLATFORM(DOM)
00357
00358 CPDOMDisplayServerInsertBefore(_DOMElement, aSubview._DOMElement, _subviews[anIndex + 1]._DOMElement);
00359 #endif
00360 }
00361
00362 [aSubview setNextResponder:self];
00363 [aSubview viewDidMoveToSuperview];
00364
00365 [self didAddSubview:aSubview];
00366 }
00367
00372 - (void)didAddSubview:(CPView)aSubview
00373 {
00374 }
00375
00380 - (void)removeFromSuperview
00381 {
00382 if (!_superview)
00383 return;
00384
00385 [_superview willRemoveSubview:self];
00386
00387 [[_superview subviews] removeObject:self];
00388
00389 #if PLATFORM(DOM)
00390 CPDOMDisplayServerRemoveChild(_superview._DOMElement, _DOMElement);
00391 #endif
00392 _superview = nil;
00393
00394 [self _setWindow:nil];
00395 }
00396
00402 - (void)replaceSubview:(CPView)aSubview with:(CPView)aView
00403 {
00404 if (aSubview._superview != self)
00405 return;
00406
00407 var index = [_subviews indexOfObjectIdenticalTo:aSubview];
00408
00409 [aSubview removeFromSuperview];
00410
00411 [self _insertSubview:aView atIndex:index];
00412 }
00413
00414
00415 - (void)_setWindow:(CPWindow)aWindow
00416 {
00417
00418 if ([_window firstResponder] == self)
00419 [_window makeFirstResponder:nil];
00420
00421
00422 [self viewWillMoveToWindow:aWindow];
00423 [_subviews makeObjectsPerformSelector:@selector(_setWindow:) withObject:aWindow];
00424
00425 _window = aWindow;
00426
00427 [self viewDidMoveToWindow];
00428 }
00429
00434 - (BOOL)isDescendantOf:(CPView)aView
00435 {
00436 var view = self;
00437
00438 do
00439 {
00440 if (view == aView)
00441 return YES;
00442 } while(view = [view superview])
00443
00444 return NO;
00445 }
00446
00450 - (void)viewDidMoveToSuperview
00451 {
00452
00453 [self setNeedsDisplay:YES];
00454 }
00455
00459 - (void)viewDidMoveToWindow
00460 {
00461 }
00462
00467 - (void)viewWillMoveToSuperview:(CPView)aView
00468 {
00469 }
00470
00475 - (void)viewWillMoveToWindow:(CPWindow)aWindow
00476 {
00477 }
00478
00483 - (void)willRemoveSubview:(CPView)aView
00484 {
00485 }
00486
00491 - (CPMenuItem)enclosingMenuItem
00492 {
00493 var view = self;
00494
00495 while (![view isKindOfClass:[_CPMenuItemView class]])
00496 view = [view superview];
00497
00498 if (view)
00499 return view._menuItem;
00500
00501 return nil;
00502
00503
00504
00505
00506
00507
00508
00509 }
00510
00511 - (int)tag
00512 {
00513 return _tag;
00514 }
00515
00520 - (BOOL)isFlipped
00521 {
00522 return YES;
00523 }
00524
00532 - (void)setFrame:(CGRect)aFrame
00533 {
00534 if (_CGRectEqualToRect(_frame, aFrame))
00535 return;
00536
00537 _inhibitFrameAndBoundsChangedNotifications = YES;
00538
00539 [self setFrameOrigin:aFrame.origin];
00540 [self setFrameSize:aFrame.size];
00541
00542 _inhibitFrameAndBoundsChangedNotifications = NO;
00543
00544 if (_postsFrameChangedNotifications)
00545 [_CPViewNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
00546 }
00547
00552 - (CGRect)frame
00553 {
00554 return _CGRectMakeCopy(_frame);
00555 }
00556
00564 - (void)setFrameOrigin:(CGPoint)aPoint
00565 {
00566 var origin = _frame.origin;
00567
00568 if (!aPoint || _CGPointEqualToPoint(origin, aPoint))
00569 return;
00570
00571 origin.x = aPoint.x;
00572 origin.y = aPoint.y;
00573
00574 if (_postsFrameChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
00575 [_CPViewNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
00576
00577 #if PLATFORM(DOM)
00578 CPDOMDisplayServerSetStyleLeftTop(_DOMElement, _superview ? _superview._boundsTransform : NULL, origin.x, origin.y);
00579 #endif
00580 }
00581
00588 - (void)setFrameSize:(CGSize)aSize
00589 {
00590 var size = _frame.size;
00591
00592 if (!aSize || _CGSizeEqualToSize(size, aSize))
00593 return;
00594
00595 var oldSize = _CGSizeMakeCopy(size);
00596
00597 size.width = aSize.width;
00598 size.height = aSize.height;
00599
00600 if (YES)
00601 {
00602 _bounds.size.width = aSize.width;
00603 _bounds.size.height = aSize.height;
00604 }
00605
00606 if (_postsFrameChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
00607 [_CPViewNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
00608
00609 if (_layer)
00610 [_layer _owningViewBoundsChanged];
00611
00612 if (_autoresizesSubviews)
00613 [self resizeSubviewsWithOldSize:oldSize];
00614
00615 [self setNeedsDisplay:YES];
00616
00617 #if PLATFORM(DOM)
00618 CPDOMDisplayServerSetStyleSize(_DOMElement, size.width, size.height);
00619
00620 if (_DOMContentsElement)
00621 {
00622 CPDOMDisplayServerSetSize(_DOMContentsElement, size.width, size.height);
00623 CPDOMDisplayServerSetStyleSize(_DOMContentsElement, size.width, size.height);
00624 }
00625
00626 if (_backgroundType == BackgroundTrivialColor)
00627 return;
00628
00629 var images = [[_backgroundColor patternImage] imageSlices];
00630
00631 if (_backgroundType == BackgroundVerticalThreePartImage)
00632 {
00633 CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width, size.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
00634 }
00635
00636 else if (_backgroundType == BackgroundHorizontalThreePartImage)
00637 {
00638 CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, size.height);
00639 }
00640
00641 else if (_backgroundType == BackgroundNinePartImage)
00642 {
00643 var width = size.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
00644 height = size.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
00645
00646 CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
00647 CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
00648 CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
00649 CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
00650 CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
00651 }
00652 #endif
00653 }
00654
00660 - (void)setBounds:(CGRect)bounds
00661 {
00662 if (_CGRectEqualToRect(_bounds, bounds))
00663 return;
00664
00665 _inhibitFrameAndBoundsChangedNotifications = YES;
00666
00667 [self setBoundsOrigin:bounds.origin];
00668 [self setBoundsSize:bounds.size];
00669
00670 _inhibitFrameAndBoundsChangedNotifications = NO;
00671
00672 if (_postsBoundsChangedNotifications)
00673 [_CPViewNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
00674 }
00675
00680 - (CGRect)bounds
00681 {
00682 return _CGRectMakeCopy(_bounds);
00683 }
00684
00691 - (void)setBoundsOrigin:(CGPoint)aPoint
00692 {
00693 var origin = _bounds.origin;
00694
00695 if (_CGPointEqualToPoint(origin, aPoint))
00696 return;
00697
00698 origin.x = aPoint.x;
00699 origin.y = aPoint.y;
00700
00701 if (origin.x != 0 || origin.y != 0)
00702 {
00703 _boundsTransform = _CGAffineTransformMakeTranslation(-origin.x, -origin.y);
00704 _inverseBoundsTransform = CGAffineTransformInvert(_boundsTransform);
00705 }
00706 else
00707 {
00708 _boundsTransform = nil;
00709 _inverseBoundsTransform = nil;
00710 }
00711
00712 #if PLATFORM(DOM)
00713 var index = _subviews.length;
00714
00715 while (index--)
00716 {
00717 var view = _subviews[index],
00718 origin = view._frame.origin;
00719
00720 CPDOMDisplayServerSetStyleLeftTop(view._DOMElement, _boundsTransform, origin.x, origin.y);
00721 }
00722 #endif
00723
00724 if (_postsBoundsChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
00725 [_CPViewNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
00726 }
00727
00734 - (void)setBoundsSize:(CGSize)aSize
00735 {
00736 var size = _bounds.size;
00737
00738 if (_CGSizeEqualToSize(size, aSize))
00739 return;
00740
00741 var frameSize = _frame.size;
00742
00743 if (!_CGSizeEqualToSize(size, frameSize))
00744 {
00745 var origin = _bounds.origin;
00746
00747 origin.x /= size.width / frameSize.width;
00748 origin.y /= size.height / frameSize.height;
00749 }
00750
00751 size.width = aSize.width;
00752 size.height = aSize.height;
00753
00754 if (!_CGSizeEqualToSize(size, frameSize))
00755 {
00756 var origin = _bounds.origin;
00757
00758 origin.x *= size.width / frameSize.width;
00759 origin.y *= size.height / frameSize.height;
00760 }
00761
00762 if (_postsBoundsChangedNotifications && !_inhibitFrameAndBoundsChangedNotifications)
00763 [_CPViewNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
00764 }
00765
00766
00771 - (void)resizeWithOldSuperviewSize:(CGSize)aSize
00772 {
00773 var mask = _autoresizingMask;
00774
00775 if(mask == CPViewNotSizable)
00776 return;
00777
00778 var frame = _superview._frame,
00779 newFrame = _CGRectMakeCopy(_frame),
00780 dX = (_CGRectGetWidth(frame) - aSize.width) /
00781 (((mask & CPViewMinXMargin) ? 1 : 0) + (mask & CPViewWidthSizable ? 1 : 0) + (mask & CPViewMaxXMargin ? 1 : 0)),
00782 dY = (_CGRectGetHeight(frame) - aSize.height) /
00783 ((mask & CPViewMinYMargin ? 1 : 0) + (mask & CPViewHeightSizable ? 1 : 0) + (mask & CPViewMaxYMargin ? 1 : 0));
00784
00785 if (mask & CPViewMinXMargin)
00786 newFrame.origin.x += dX;
00787 if (mask & CPViewWidthSizable)
00788 newFrame.size.width += dX;
00789
00790 if (mask & CPViewMinYMargin)
00791 newFrame.origin.y += dY;
00792 if (mask & CPViewHeightSizable)
00793 newFrame.size.height += dY;
00794
00795 [self setFrame:newFrame];
00796 }
00797
00802 - (void)resizeSubviewsWithOldSize:(CGSize)aSize
00803 {
00804 var count = _subviews.length;
00805
00806 while (count--)
00807 [_subviews[count] resizeWithOldSuperviewSize:aSize];
00808 }
00809
00817 - (void)setAutoresizesSubviews:(BOOL)aFlag
00818 {
00819 _autoresizesSubviews = aFlag;
00820 }
00821
00826 - (BOOL)autoresizesSubviews
00827 {
00828 return _autoresizesSubviews;
00829 }
00830
00835 - (void)setAutoresizingMask:(unsigned)aMask
00836 {
00837 _autoresizingMask = aMask;
00838 }
00839
00843 - (unsigned)autoresizingMask
00844 {
00845 return _autoresizingMask;
00846 }
00847
00848
00854 - (BOOL)enterFullScreenMode:(CPScreen)aScreen withOptions:(CPDictionary)options
00855 {
00856 _fullScreenModeState = _CPViewFullScreenModeStateMake(self);
00857
00858 var fullScreenWindow = [[CPWindow alloc] initWithContentRect:[[CPDOMWindowBridge sharedDOMWindowBridge] contentBounds] styleMask:CPBorderlessWindowMask];
00859
00860 [fullScreenWindow setLevel:CPScreenSaverWindowLevel];
00861 [fullScreenWindow setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
00862
00863 var contentView = [fullScreenWindow contentView];
00864
00865 [contentView setBackgroundColor:[CPColor blackColor]];
00866 [contentView addSubview:self];
00867
00868 [self setAutoresizingMask:CPViewWidthSizable | CPViewHeightSizable];
00869 [self setFrame:CGRectMakeCopy([contentView bounds])];
00870
00871 [fullScreenWindow makeKeyAndOrderFront:self];
00872
00873 [fullScreenWindow makeFirstResponder:self];
00874
00875 _isInFullScreenMode = YES;
00876
00877 return YES;
00878 }
00879
00884 - (void)exitFullScreenModeWithOptions:(CPDictionary)options
00885 {
00886 if (!_isInFullScreenMode)
00887 return;
00888
00889 _isInFullScreenMode = NO;
00890
00891 [self setFrame:_fullScreenModeState.frame];
00892 [self setAutoresizingMask:_fullScreenModeState.autoresizingMask];
00893 [_fullScreenModeState.superview _insertSubview:self atIndex:_fullScreenModeState.index];
00894
00895 [[self window] orderOut:self];
00896 }
00897
00901 - (BOOL)isInFullScreenMode
00902 {
00903 return _isInFullScreenMode;
00904 }
00905
00910 - (void)setHidden:(BOOL)aFlag
00911 {
00912 if(_isHidden == aFlag)
00913 return;
00914
00915
00916 _isHidden = aFlag;
00917 #if PLATFORM(DOM)
00918 _DOMElement.style.display = _isHidden ? "none" : "block";
00919 #endif
00920 }
00921
00925 - (BOOL)isHidden
00926 {
00927 return _isHidden;
00928 }
00929
00935 - (void)setAlphaValue:(float)anAlphaValue
00936 {
00937 if (_opacity == anAlphaValue)
00938 return;
00939
00940 _opacity = anAlphaValue;
00941
00942 #if PLATFORM(DOM)
00943
00944 if (CPFeatureIsCompatible(CPOpacityRequiresFilterFeature))
00945 {
00946 if (anAlphaValue == 1.0)
00947 try { _DOMElement.style.removeAttribute("filter") } catch (anException) { }
00948 else
00949 _DOMElement.style.filter = "alpha(opacity=" + anAlphaValue * 100 + ")";
00950 }
00951 else
00952 _DOMElement.style.opacity = anAlphaValue;
00953
00954 #endif
00955 }
00956
00961 - (float)alphaValue
00962 {
00963 return _opacity;
00964 }
00965
00970 - (BOOL)isHiddenOrHasHiddenAncestor
00971 {
00972 var view = self;
00973
00974 while (![view isHidden])
00975 view = [view superview];
00976
00977 return view != nil;
00978 }
00979
00985
00986 - (BOOL)acceptsFirstMouse:(CPEvent)anEvent
00987 {
00988 return YES;
00989 }
00990
00995 - (BOOL)hitTests
00996 {
00997 return _hitTests;
00998 }
00999
01004 - (void)setHitTests:(BOOL)shouldHitTest
01005 {
01006 _hitTests = shouldHitTest;
01007 }
01008
01014 - (CPView)hitTest:(CPPoint)aPoint
01015 {
01016 if(_isHidden || !_hitTests || !CPRectContainsPoint(_frame, aPoint))
01017 return nil;
01018
01019 var view = nil,
01020 i = _subviews.length,
01021 adjustedPoint = _CGPointMake(aPoint.x - _CGRectGetMinX(_frame), aPoint.y - _CGRectGetMinY(_frame));
01022
01023 if (_inverseBoundsTransform)
01024 adjustedPoint = _CGPointApplyAffineTransform(adjustedPoint, _inverseBoundsTransform);
01025
01026 while (i--)
01027 if (view = [_subviews[i] hitTest:adjustedPoint])
01028 return view;
01029
01030 return self;
01031 }
01032
01037 - (BOOL)mouseDownCanMoveWindow
01038 {
01039 return ![self isOpaque];
01040 }
01041
01042 - (void)mouseDown:(CPEvent)anEvent
01043 {
01044 if ([self mouseDownCanMoveWindow])
01045 [super mouseDown:anEvent];
01046 }
01047
01052 - (void)setBackgroundColor:(CPColor)aColor
01053 {
01054 if (_backgroundColor == aColor)
01055 return;
01056
01057 _backgroundColor = aColor;
01058
01059 #if PLATFORM(DOM)
01060 var patternImage = [_backgroundColor patternImage],
01061 amount = 0;
01062
01063 if ([patternImage isThreePartImage])
01064 {
01065 _backgroundType = [patternImage isVertical] ? BackgroundVerticalThreePartImage : BackgroundHorizontalThreePartImage;
01066
01067 amount = 3 - _DOMImageParts.length;
01068 }
01069 else if ([patternImage isNinePartImage])
01070 {
01071 _backgroundType = BackgroundNinePartImage;
01072
01073 amount = 9 - _DOMImageParts.length;
01074 }
01075 else
01076 {
01077 _backgroundType = BackgroundTrivialColor;
01078
01079 amount = 0 - _DOMImageParts.length;
01080 }
01081
01082 if (amount > 0)
01083 while (amount--)
01084 {
01085 var DOMElement = DOMElementPrototype.cloneNode(false);
01086
01087 DOMElement.style.zIndex = -1000;
01088
01089 _DOMImageParts.push(DOMElement);
01090 _DOMElement.appendChild(DOMElement);
01091 }
01092 else
01093 {
01094 amount = -amount;
01095
01096 while (amount--)
01097 _DOMElement.removeChild(_DOMImageParts.pop());
01098 }
01099
01100 if (_backgroundType == BackgroundTrivialColor)
01101
01102
01103
01104 _DOMElement.style.background = _backgroundColor ? [_backgroundColor cssString] : "";
01105
01106 else
01107 {
01108 var slices = [patternImage imageSlices],
01109 count = slices.length,
01110 frameSize = _frame.size;
01111
01112 while (count--)
01113 {
01114 var image = slices[count],
01115 size = _DOMImageSizes[count] = image ? [image size] : _CGSizeMakeZero();
01116
01117 CPDOMDisplayServerSetStyleSize(_DOMImageParts[count], size.width, size.height);
01118
01119 _DOMImageParts[count].style.background = image ? "url(\"" + [image filename] + "\")" : "";
01120 }
01121
01122 if (_backgroundType == BackgroundNinePartImage)
01123 {
01124 var width = frameSize.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width,
01125 height = frameSize.height - _DOMImageSizes[0].height - _DOMImageSizes[6].height;
01126
01127 CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], width, _DOMImageSizes[0].height);
01128 CPDOMDisplayServerSetStyleSize(_DOMImageParts[3], _DOMImageSizes[3].width, height);
01129 CPDOMDisplayServerSetStyleSize(_DOMImageParts[4], width, height);
01130 CPDOMDisplayServerSetStyleSize(_DOMImageParts[5], _DOMImageSizes[5].width, height);
01131 CPDOMDisplayServerSetStyleSize(_DOMImageParts[7], width, _DOMImageSizes[7].height);
01132
01133 CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
01134 CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
01135 CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[2], NULL, 0.0, 0.0);
01136 CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[3], NULL, 0.0, _DOMImageSizes[1].height);
01137 CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[4], NULL, _DOMImageSizes[0].width, _DOMImageSizes[0].height);
01138 CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[5], NULL, 0.0, _DOMImageSizes[1].height);
01139 CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[6], NULL, 0.0, 0.0);
01140 CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[7], NULL, _DOMImageSizes[6].width, 0.0);
01141 CPDOMDisplayServerSetStyleRightBottom(_DOMImageParts[8], NULL, 0.0, 0.0);
01142 }
01143 else if (_backgroundType == BackgroundVerticalThreePartImage)
01144 {
01145 CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], frameSize.width, frameSize.height - _DOMImageSizes[0].height - _DOMImageSizes[2].height);
01146
01147 CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
01148 CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, 0.0, _DOMImageSizes[0].height);
01149 CPDOMDisplayServerSetStyleLeftBottom(_DOMImageParts[2], NULL, 0.0, 0.0);
01150 }
01151 else if (_backgroundType == BackgroundHorizontalThreePartImage)
01152 {
01153 CPDOMDisplayServerSetStyleSize(_DOMImageParts[1], frameSize.width - _DOMImageSizes[0].width - _DOMImageSizes[2].width, frameSize.height);
01154
01155 CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[0], NULL, 0.0, 0.0);
01156 CPDOMDisplayServerSetStyleLeftTop(_DOMImageParts[1], NULL, _DOMImageSizes[0].width, 0.0);
01157 CPDOMDisplayServerSetStyleRightTop(_DOMImageParts[2], NULL, 0.0, 0.0);
01158 }
01159 }
01160 #endif
01161 }
01162
01166 - (CPColor)backgroundColor
01167 {
01168 return _backgroundColor;
01169 }
01170
01171
01178 - (CGPoint)convertPoint:(CGPoint)aPoint fromView:(CPView)aView
01179 {
01180 return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(aView, self));
01181 }
01182
01189 - (CGPoint)convertPoint:(CGPoint)aPoint toView:(CPView)aView
01190 {
01191 return CGPointApplyAffineTransform(aPoint, _CPViewGetTransform(self, aView));
01192 }
01193
01200 - (CGSize)convertSize:(CGSize)aSize fromView:(CPView)aView
01201 {
01202 return CGSizeApplyAffineTransform(aSize, _CPViewGetTransform(aView, self));
01203 }
01204
01211 - (CGSize)convertSize:(CGSize)aSize toView:(CPView)aView
01212 {
01213 return CGSizeApplyAffineTransform(aSize, _CPViewGetTransform(self, aView));
01214 }
01215
01222 - (CGRect)convertRect:(CGRect)aRect fromView:(CPView)aView
01223 {
01224 return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(aView, self));
01225 }
01226
01233 - (CGRect)convertRect:(CGRect)aRect toView:(CPView)aView
01234 {
01235 return CGRectApplyAffineTransform(aRect, _CPViewGetTransform(self, aView));
01236 }
01237
01250 - (void)setPostsFrameChangedNotifications:(BOOL)shouldPostFrameChangedNotifications
01251 {
01252 if (_postsFrameChangedNotifications == shouldPostFrameChangedNotifications)
01253 return;
01254
01255 _postsFrameChangedNotifications = shouldPostFrameChangedNotifications;
01256
01257 if (_postsFrameChangedNotifications)
01258 [_CPViewNotificationCenter postNotificationName:CPViewFrameDidChangeNotification object:self];
01259 }
01260
01264 - (BOOL)postsFrameChangedNotifications
01265 {
01266 return _postsFrameChangedNotifications;
01267 }
01268
01281 - (void)setPostsBoundsChangedNotifications:(BOOL)shouldPostBoundsChangedNotifications
01282 {
01283 if (_postsBoundsChangedNotifications == shouldPostBoundsChangedNotifications)
01284 return;
01285
01286 _postsBoundsChangedNotifications = shouldPostBoundsChangedNotifications;
01287
01288 if (_postsBoundsChangedNotifications)
01289 [_CPViewNotificationCenter postNotificationName:CPViewBoundsDidChangeNotification object:self];
01290 }
01291
01297 - (BOOL)postsBoundsChangedNotifications
01298 {
01299 return _postsBoundsChangedNotifications;
01300 }
01301
01312 - (void)dragImage:(CPImage)anImage at:(CGPoint)aLocation offset:(CGSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
01313 {
01314 [_window dragImage:anImage at:[self convertPoint:aLocation toView:nil] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack];
01315 }
01316
01327 - (void)dragView:(CPView)aView at:(CPPoint)aLocation offset:(CPSize)mouseOffset event:(CPEvent)anEvent pasteboard:(CPPasteboard)aPasteboard source:(id)aSourceObject slideBack:(BOOL)slideBack
01328 {
01329 [_window dragView:aView at:[self convertPoint:aLocation toView:nil] offset:mouseOffset event:anEvent pasteboard:aPasteboard source:aSourceObject slideBack:slideBack];
01330 }
01331
01336 - (void)registerForDraggedTypes:(CPArray)pasteboardTypes
01337 {
01338 _registeredDraggedTypes = [pasteboardTypes copy];
01339 }
01340
01345 - (CPArray)registeredDraggedTypes
01346 {
01347 return _registeredDraggedTypes;
01348 }
01349
01353 - (void)unregisterDraggedTypes
01354 {
01355 _registeredDraggedTypes = nil;
01356 }
01357
01362 - (void)drawRect:(CPRect)aRect
01363 {
01364
01365 }
01366
01367
01368
01372 - (void)setNeedsDisplay:(BOOL)aFlag
01373 {
01374 if (aFlag)
01375 [self setNeedsDisplayInRect:[self bounds]];
01376 #if PLATFORM(DOM)
01377 else
01378 CPDOMDisplayServerRemoveView(self);
01379 #endif
01380 }
01381
01386 - (void)setNeedsDisplayInRect:(CPRect)aRect
01387 {
01388 #if PLATFORM(DOM)
01389 var hash = [[self class] hash],
01390 hasCustomDrawRect = CustomDrawRectViews[hash];
01391
01392 if (!hasCustomDrawRect && typeof hasCustomDrawRect === "undefined")
01393 {
01394 hasCustomDrawRect = [self methodForSelector:@selector(drawRect:)] != [CPView instanceMethodForSelector:@selector(drawRect:)];
01395 CustomDrawRectViews[hash] = hasCustomDrawRect;
01396 }
01397
01398 if (!hasCustomDrawRect)
01399 return;
01400 #endif
01401
01402 if (_CGRectIsEmpty(aRect))
01403 return;
01404
01405 if (_dirtyRect && !_CGRectIsEmpty(_dirtyRect))
01406 _dirtyRect = CGRectUnion(aRect, _dirtyRect);
01407 else
01408 _dirtyRect = _CGRectMakeCopy(aRect);
01409
01410 #if PLATFORM(DOM)
01411 CPDOMDisplayServerAddView(self);
01412 #endif
01413 }
01414
01415 - (BOOL)needsDisplay
01416 {
01417 return _dirtyRect && !_CGRectIsEmpty(_dirtyRect);
01418 }
01419
01423 - (void)displayIfNeeded
01424 {
01425 if ([self needsDisplay])
01426 [self displayRect:_dirtyRect];
01427 }
01428
01432 - (void)display
01433 {
01434 [self displayRect:[self visibleRect]];
01435 }
01436
01437 - (void)displayIfNeededInRect:(CGRect)aRect
01438 {
01439 if ([self needsDisplay])
01440 [self displayRect:aRect];
01441 }
01442
01447 - (void)displayRect:(CPRect)aRect
01448 {
01449 [self viewWillDraw];
01450
01451 [self displayRectIgnoringOpacity:aRect inContext:nil];
01452
01453 _dirtyRect = NULL;
01454 }
01455
01456 - (void)displayRectIgnoringOpacity:(CGRect)aRect inContext:(CPGraphicsContext)aGraphicsContext
01457 {
01458 [self lockFocus];
01459
01460 CGContextClearRect([[CPGraphicsContext currentContext] graphicsPort], aRect);
01461
01462 [self drawRect:aRect];
01463 [self unlockFocus];
01464 }
01465
01466 - (void)viewWillDraw
01467 {
01468 }
01469
01473 - (void)lockFocus
01474 {
01475 if (!_graphicsContext)
01476 {
01477 var graphicsPort = CGBitmapGraphicsContextCreate();
01478
01479 _DOMContentsElement = graphicsPort.DOMElement;
01480
01481 _DOMContentsElement.style.zIndex = -100;
01482
01483 _DOMContentsElement.style.overflow = "hidden";
01484 _DOMContentsElement.style.position = "absolute";
01485 _DOMContentsElement.style.visibility = "visible";
01486
01487 _DOMContentsElement.width = ROUND(_CGRectGetWidth(_frame));
01488 _DOMContentsElement.height = ROUND(_CGRectGetHeight(_frame));
01489
01490 _DOMContentsElement.style.top = "0px";
01491 _DOMContentsElement.style.left = "0px";
01492 _DOMContentsElement.style.width = ROUND(_CGRectGetWidth(_frame)) + "px";
01493 _DOMContentsElement.style.height = ROUND(_CGRectGetHeight(_frame)) + "px";
01494
01495 CPDOMDisplayServerAppendChild(_DOMElement, _DOMContentsElement);
01496
01497 _graphicsContext = [CPGraphicsContext graphicsContextWithGraphicsPort:graphicsPort flipped:YES];
01498 }
01499
01500 [CPGraphicsContext setCurrentContext:_graphicsContext];
01501
01502 CGContextSaveGState([_graphicsContext graphicsPort]);
01503 }
01504
01508 - (void)unlockFocus
01509 {
01510 CGContextRestoreGState([_graphicsContext graphicsPort]);
01511
01512 [CPGraphicsContext setCurrentContext:nil];
01513 }
01514
01518 - (BOOL)isOpaque
01519 {
01520 return NO;
01521 }
01522
01526 - (CGRect)visibleRect
01527 {
01528 if (!_superview)
01529 return _bounds;
01530
01531 return CGRectIntersection([self convertRect:[_superview visibleRect] fromView:_superview], _bounds);
01532 }
01533
01534
01535
01536 - (CPScrollView)_enclosingClipView
01537 {
01538 var superview = _superview,
01539 clipViewClass = [CPClipView class];
01540
01541 while(superview && ![superview isKindOfClass:clipViewClass])
01542 superview = superview._superview;
01543
01544 return superview;
01545 }
01546
01551 - (void)scrollPoint:(CGPoint)aPoint
01552 {
01553 var clipView = [self _enclosingClipView];
01554
01555 if (!clipView)
01556 return;
01557
01558 [clipView scrollToPoint:[self convertPoint:aPoint toView:clipView]];
01559 }
01560
01566 - (BOOL)scrollRectToVisible:(CGRect)aRect
01567 {
01568 var visibleRect = [self visibleRect];
01569
01570
01571 aRect = CGRectIntersection(aRect, _bounds);
01572
01573
01574 if (_CGRectIsEmpty(aRect) || CGRectContainsRect(visibleRect, aRect))
01575 return NO;
01576
01577 var enclosingClipView = [self _enclosingClipView];
01578
01579
01580 if (!enclosingClipView)
01581 return NO;
01582
01583 var scrollPoint = _CGPointMakeCopy(visibleRect.origin);
01584
01585
01586 if (_CGRectGetMinX(aRect) <= _CGRectGetMinX(visibleRect))
01587 scrollPoint.x = _CGRectGetMinX(aRect);
01588 else if (_CGRectGetMaxX(aRect) > _CGRectGetMaxX(visibleRect))
01589 scrollPoint.x += _CGRectGetMaxX(aRect) - _CGRectGetMaxX(visibleRect);
01590
01591 if (_CGRectGetMinY(aRect) <= _CGRectGetMinY(visibleRect))
01592 scrollPoint.y = CGRectGetMinY(aRect);
01593 else if (_CGRectGetMaxY(aRect) > _CGRectGetMaxY(visibleRect))
01594 scrollPoint.y += _CGRectGetMaxY(aRect) - _CGRectGetMaxY(visibleRect);
01595
01596 [enclosingClipView scrollToPoint:CGPointMake(scrollPoint.x, scrollPoint.y)];
01597
01598 return YES;
01599 }
01600
01601
01602
01603
01604 - (BOOL)autoscroll:(CPEvent)anEvent
01605 {
01606
01607 return NO;
01608 }
01609
01616 - (CGRect)adjustScroll:(CGRect)proposedVisibleRect
01617 {
01618 return proposedVisibleRect;
01619 }
01620
01624 - (void)scrollRect:(CGRect)aRect by:(float)anAmount
01625 {
01626
01627 }
01628
01633 - (CPScrollView)enclosingScrollView
01634 {
01635 var superview = _superview,
01636 scrollViewClass = [CPScrollView class];
01637
01638 while(superview && ![superview isKindOfClass:scrollViewClass])
01639 superview = superview._superview;
01640
01641 return superview;
01642 }
01643
01649 - (void)scrollClipView:(CPClipView)aClipView toPoint:(CGPoint)aPoint
01650 {
01651 [aClipView scrollToPoint:aPoint];
01652 }
01653
01659 - (void)reflectScrolledClipView:(CPClipView)aClipView
01660 {
01661 }
01662
01663 @end
01664
01665 @implementation CPView (CoreAnimationAdditions)
01666
01670 - (void)setLayer:(CALayer)aLayer
01671 {
01672 if (_layer == aLayer)
01673 return;
01674
01675 if (_layer)
01676 {
01677 _layer._owningView = nil;
01678 #if PLATFORM(DOM)
01679 _DOMElement.removeChild(_layer._DOMElement);
01680 #endif
01681 }
01682
01683 _layer = aLayer;
01684
01685 if (_layer)
01686 {
01687 var bounds = CGRectMakeCopy([self bounds]);
01688
01689 [_layer _setOwningView:self];
01690
01691 #if PLATFORM(DOM)
01692 _layer._DOMElement.style.zIndex = 100;
01693
01694 _DOMElement.appendChild(_layer._DOMElement);
01695 #endif
01696 }
01697 }
01698
01702 - (CALayer)layer
01703 {
01704 return _layer;
01705 }
01706
01711 - (void)setWantsLayer:(BOOL)aFlag
01712 {
01713 _wantsLayer = aFlag;
01714 }
01715
01720 - (BOOL)wantsLayer
01721 {
01722 return _wantsLayer;
01723 }
01724
01725 @end
01726
01727 var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
01728 CPViewAutoresizesSubviewsKey = @"CPViewAutoresizesSubviews",
01729 CPViewBackgroundColorKey = @"CPViewBackgroundColor",
01730 CPViewBoundsKey = @"CPViewBoundsKey",
01731 CPViewFrameKey = @"CPViewFrameKey",
01732 CPViewHitTestsKey = @"CPViewHitTestsKey",
01733 CPViewIsHiddenKey = @"CPViewIsHiddenKey",
01734 CPViewOpacityKey = @"CPViewOpacityKey",
01735 CPViewSubviewsKey = @"CPViewSubviewsKey",
01736 CPViewSuperviewKey = @"CPViewSuperviewKey",
01737 CPViewTagKey = @"CPViewTagKey",
01738 CPViewWindowKey = @"CPViewWindowKey";
01739
01740 @implementation CPView (CPCoding)
01741
01747 - (id)initWithCoder:(CPCoder)aCoder
01748 {
01749
01750
01751
01752
01753 #if PLATFORM(DOM)
01754 _DOMElement = DOMElementPrototype.cloneNode(false);
01755 #endif
01756
01757
01758 _frame = [aCoder decodeRectForKey:CPViewFrameKey];
01759 _bounds = [aCoder decodeRectForKey:CPViewBoundsKey];
01760
01761 self = [super initWithCoder:aCoder];
01762
01763 if (self)
01764 {
01765 _tag = -1;
01766
01767 if ([aCoder containsValueForKey:CPViewTagKey])
01768 _tag = [aCoder decodeIntForKey:CPViewTagKey];
01769
01770 _window = [aCoder decodeObjectForKey:CPViewWindowKey];
01771 _subviews = [aCoder decodeObjectForKey:CPViewSubviewsKey];
01772 _superview = [aCoder decodeObjectForKey:CPViewSuperviewKey];
01773
01774 _autoresizingMask = [aCoder decodeIntForKey:CPViewAutoresizingMaskKey];
01775 _autoresizesSubviews = [aCoder decodeBoolForKey:CPViewAutoresizesSubviewsKey];
01776
01777 _hitTests = [aCoder decodeObjectForKey:CPViewHitTestsKey];
01778 _isHidden = [aCoder decodeObjectForKey:CPViewIsHiddenKey];
01779 _opacity = [aCoder decodeIntForKey:CPViewOpacityKey];
01780
01781
01782 #if PLATFORM(DOM)
01783 _DOMImageParts = [];
01784 _DOMImageSizes = [];
01785
01786 CPDOMDisplayServerSetStyleLeftTop(_DOMElement, NULL, _CGRectGetMinX(_frame), _CGRectGetMinY(_frame));
01787 CPDOMDisplayServerSetStyleSize(_DOMElement, _CGRectGetWidth(_frame), _CGRectGetHeight(_frame));
01788
01789 var index = 0,
01790 count = _subviews.length;
01791
01792 for (; index < count; ++index)
01793 {
01794 CPDOMDisplayServerAppendChild(_DOMElement, _subviews[index]._DOMElement);
01795
01796 }
01797 #endif
01798 _displayHash = [self hash];
01799
01800 [self setBackgroundColor:[aCoder decodeObjectForKey:CPViewBackgroundColorKey]];
01801
01802 [self setNeedsDisplay:YES];
01803 }
01804
01805 return self;
01806 }
01807
01812 - (void)encodeWithCoder:(CPCoder)aCoder
01813 {
01814 [super encodeWithCoder:aCoder];
01815
01816 if (_tag != -1)
01817 [aCoder encodeInt:_tag forKey:CPViewTagKey];
01818
01819 [aCoder encodeRect:_frame forKey:CPViewFrameKey];
01820 [aCoder encodeRect:_bounds forKey:CPViewBoundsKey];
01821
01822 [aCoder encodeConditionalObject:_window forKey:CPViewWindowKey];
01823 [aCoder encodeObject:_subviews forKey:CPViewSubviewsKey];
01824 [aCoder encodeConditionalObject:_superview forKey:CPViewSuperviewKey];
01825
01826 [aCoder encodeInt:_autoresizingMask forKey:CPViewAutoresizingMaskKey];
01827 [aCoder encodeBool:_autoresizesSubviews forKey:CPViewAutoresizesSubviewsKey];
01828
01829 [aCoder encodeObject:_backgroundColor forKey:CPViewBackgroundColorKey];
01830
01831 [aCoder encodeBool:_hitTests forKey:CPViewHitTestsKey];
01832 [aCoder encodeBool:_isHidden forKey:CPViewIsHiddenKey];
01833 [aCoder encodeFloat:_opacity forKey:CPViewOpacityKey];
01834 }
01835
01836 @end
01837
01838 var _CPViewFullScreenModeStateMake = function(aView)
01839 {
01840 var superview = aView._superview;
01841
01842 return { autoresizingMask:aView._autoresizingMask, frame:CGRectMakeCopy(aView._frame), index:(superview ? [superview._subviews indexOfObjectIdenticalTo:aView] : 0), superview:superview };
01843 }
01844
01845 var _CPViewGetTransform = function( fromView, toView)
01846 {
01847 var transform = CGAffineTransformMakeIdentity();
01848
01849 if (fromView)
01850 {
01851 var view = fromView;
01852
01853
01854
01855 while (view && view != toView)
01856 {
01857 var frame = view._frame;
01858
01859 transform.tx += _CGRectGetMinX(frame);
01860 transform.ty += _CGRectGetMinY(frame);
01861
01862 if (view._boundsTransform)
01863 {
01864 _CGAffineTransformConcatTo(transform, view._boundsTransform, transform);
01865 }
01866
01867 view = view._superview;
01868 }
01869
01870
01871 if (view == toView)
01872 return transform;
01873 }
01874
01875
01876 var view = toView;
01877
01878 while (view)
01879 {
01880 var frame = view._frame;
01881
01882 transform.tx -= _CGRectGetMinX(frame);
01883 transform.ty -= _CGRectGetMinY(frame);
01884
01885 if (view._boundsTransform)
01886 {
01887 _CGAffineTransformConcatTo(transform, view._inverseBoundsTransform, transform);
01888 }
01889
01890 view = view._superview;
01891 }
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912 return transform;
01913 }