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 if([superview isKindOfClass:[CPScrollView class]])
00126 [superview reflectScrolledClipView:self];
00127 }
00128
00133 - (void)scrollToPoint:(CGPoint)aPoint
00134 {
00135 [self setBoundsOrigin:[self constrainScrollPoint:aPoint]];
00136 }
00137
00142 - (void)viewBoundsChanged:(CPNotification)aNotification
00143 {
00144 [self _constrainScrollPoint];
00145 }
00146
00151 - (void)viewFrameChanged:(CPNotification)aNotification
00152 {
00153 [self _constrainScrollPoint];
00154 }
00155
00156 - (void)resizeSubviewsWithOldSize:(CGSize)aSize
00157 {
00158 [super resizeSubviewsWithOldSize:aSize];
00159 [self _constrainScrollPoint];
00160 }
00161
00162 - (void)_constrainScrollPoint
00163 {
00164 var oldScrollPoint = [self bounds].origin;
00165
00166
00167
00168 [self scrollToPoint:oldScrollPoint];
00169
00170
00171
00172 if (!CGPointEqualToPoint(oldScrollPoint, [self bounds].origin))
00173 return;
00174
00175
00176 var superview = [self superview];
00177
00178 if ([superview isKindOfClass:[CPScrollView class]])
00179 [superview reflectScrolledClipView:self];
00180 }
00181
00182 - (BOOL)autoscroll:(CPEvent)anEvent
00183 {
00184 var bounds = [self bounds],
00185 eventLocation = [self convertPoint:[anEvent locationInWindow] fromView:nil];
00186
00187 if (CPRectContainsPoint(bounds, eventLocation))
00188 return NO;
00189
00190 var newRect = CGRectMakeZero();
00191
00192 newRect.origin = eventLocation;
00193 newRect.size = CPSizeMake(10, 10);
00194
00195 return [_documentView scrollRectToVisible:newRect];
00196 }
00197
00198 @end
00199
00200
00201 var CPClipViewDocumentViewKey = @"CPScrollViewDocumentView";
00202
00203 @implementation CPClipView (CPCoding)
00204
00205 - (id)initWithCoder:(CPCoder)aCoder
00206 {
00207 if (self = [super initWithCoder:aCoder])
00208 [self setDocumentView:[aCoder decodeObjectForKey:CPClipViewDocumentViewKey]];
00209
00210 return self;
00211 }
00212
00213 - (void)encodeWithCoder:(CPCoder)aCoder
00214 {
00215 [super encodeWithCoder:aCoder];
00216
00217 [aCoder encodeObject:_documentView forKey:CPClipViewDocumentViewKey];
00218 }
00219
00220 @end