00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import "CPView.j"
00024
00025 #include "CoreGraphics/CGGeometry.h"
00026
00027
00035 @implementation CPClipView : CPView
00036 {
00037 CPView _documentView;
00038 }
00039
00044 - (void)setDocumentView:(CPView)aView
00045 {
00046 if (_documentView == aView)
00047 return;
00048
00049 var defaultCenter = [CPNotificationCenter defaultCenter];
00050
00051 if (_documentView)
00052 {
00053 [defaultCenter
00054 removeObserver:self
00055 name:CPViewFrameDidChangeNotification
00056 object:_documentView];
00057
00058 [defaultCenter
00059 removeObserver:self
00060 name:CPViewBoundsDidChangeNotification
00061 object:_documentView];
00062
00063 [_documentView removeFromSuperview];
00064 }
00065
00066 _documentView = aView;
00067
00068 if (_documentView)
00069 {
00070 [self addSubview:_documentView];
00071
00072 [_documentView setPostsFrameChangedNotifications:YES];
00073 [_documentView setPostsBoundsChangedNotifications:YES];
00074
00075 [defaultCenter
00076 addObserver:self
00077 selector:@selector(viewFrameChanged:)
00078 name:CPViewFrameDidChangeNotification
00079 object:_documentView];
00080
00081 [defaultCenter
00082 addObserver:self
00083 selector:@selector(viewBoundsChanged:)
00084 name:CPViewBoundsDidChangeNotification
00085 object:_documentView];
00086 }
00087 }
00088
00092 - (id)documentView
00093 {
00094 return _documentView;
00095 }
00096
00103 - (CGPoint)constrainScrollPoint:(CGPoint)aPoint
00104 {
00105 if (!_documentView)
00106 return _CGPointMakeZero();
00107
00108 var documentFrame = [_documentView frame];
00109
00110 aPoint.x = MAX(0.0, MIN(aPoint.x, MAX(_CGRectGetWidth(documentFrame) - _CGRectGetWidth(_bounds), 0.0)));
00111 aPoint.y = MAX(0.0, MIN(aPoint.y, MAX(_CGRectGetHeight(documentFrame) - _CGRectGetHeight(_bounds), 0.0)));
00112
00113 return aPoint;
00114 }
00115
00116 - (void)setBoundsOrigin:(CGPoint)aPoint
00117 {
00118 if (_CGPointEqualToPoint(_bounds.origin, aPoint))
00119 return;
00120
00121 [super setBoundsOrigin:aPoint];
00122
00123 var superview = [self superview],
00124
00125
00126
00127 scrollViewClass = objj_getClass("CPScrollView");
00128
00129 if([superview isKindOfClass:scrollViewClass])
00130 [superview reflectScrolledClipView:self];
00131 }
00132
00137 - (void)scrollToPoint:(CGPoint)aPoint
00138 {
00139 [self setBoundsOrigin:[self constrainScrollPoint:aPoint]];
00140 }
00141
00146 - (void)viewBoundsChanged:(CPNotification)aNotification
00147 {
00148 [self _constrainScrollPoint];
00149 }
00150
00155 - (void)viewFrameChanged:(CPNotification)aNotification
00156 {
00157 [self _constrainScrollPoint];
00158 }
00159
00160 - (void)resizeSubviewsWithOldSize:(CGSize)aSize
00161 {
00162 [super resizeSubviewsWithOldSize:aSize];
00163 [self _constrainScrollPoint];
00164 }
00165
00166 - (void)_constrainScrollPoint
00167 {
00168 var oldScrollPoint = [self bounds].origin;
00169
00170
00171
00172 [self scrollToPoint:oldScrollPoint];
00173
00174
00175
00176 if (!CGPointEqualToPoint(oldScrollPoint, [self bounds].origin))
00177 return;
00178
00179
00180 var superview = [self superview],
00181
00182
00183
00184 scrollViewClass = objj_getClass("CPScrollView");
00185
00186 if ([superview isKindOfClass:scrollViewClass])
00187 [superview reflectScrolledClipView:self];
00188 }
00189
00190 - (BOOL)autoscroll:(CPEvent)anEvent
00191 {
00192 var bounds = [self bounds],
00193 eventLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil];
00194
00195 if (CPRectContainsPoint(bounds, eventLocation))
00196 return NO;
00197
00198 var newRect = CGRectMakeZero();
00199
00200 newRect.origin = eventLocation;
00201 newRect.size = CPSizeMake(10, 10);
00202
00203 return [_documentView scrollRectToVisible:newRect];
00204 }
00205
00206 @end
00207
00208
00209 var CPClipViewDocumentViewKey = @"CPScrollViewDocumentView";
00210
00211 @implementation CPClipView (CPCoding)
00212
00213 - (id)initWithCoder:(CPCoder)aCoder
00214 {
00215 if (self = [super initWithCoder:aCoder])
00216 [self setDocumentView:[aCoder decodeObjectForKey:CPClipViewDocumentViewKey]];
00217
00218 return self;
00219 }
00220
00221 - (void)encodeWithCoder:(CPCoder)aCoder
00222 {
00223 [super encodeWithCoder:aCoder];
00224
00225 [aCoder encodeObject:_documentView forKey:CPClipViewDocumentViewKey];
00226 }
00227
00228 @end