Skip to content

Commit eeab562

Browse files
committed
Merge branch 'develop-v3' of github:cocos2d/cocos2d-iphone into develop-v3
Former-commit-id: cff37c6
2 parents 4221fa4 + 0146193 commit eeab562

File tree

5 files changed

+233
-38
lines changed

5 files changed

+233
-38
lines changed

cocos2d-ui-tests/tests/CCScrollViewTest.m

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
#import "TestBase.h"
2626

27-
@interface CCScrollViewTest : TestBase @end
27+
@interface CCScrollViewTest : TestBase <CCScrollViewDelegate> @end
2828

2929
@implementation CCScrollViewTest
3030

@@ -46,10 +46,36 @@ - (void)setupScrollViewBasicTest
4646

4747
CCScrollView* scrollView = [[CCScrollView alloc] initWithContentNode:[self createScrollContent]];
4848
scrollView.flipYCoordinates = NO;
49+
scrollView.delegate = self;
4950

5051
[self.contentNode addChild:scrollView];
5152
}
5253

54+
- (void)scrollViewDidEndDecelerating:(CCScrollView *)scrollView
55+
{
56+
CCLOG(@"did end decelerating");
57+
}
58+
59+
- (void)scrollViewDidEndDragging:(CCScrollView *)scrollView willDecelerate:(BOOL)decelerate
60+
{
61+
CCLOG(@"did end dragging, decelerate: %@", decelerate ? @"YES" : @"NO");
62+
}
63+
64+
- (void)scrollViewWillBeginDecelerating:(CCScrollView *)scrollView
65+
{
66+
CCLOG(@"will begin decelerating");
67+
}
68+
69+
- (void)scrollViewWillBeginDragging:(CCScrollView *)scrollView
70+
{
71+
CCLOG(@"will begin dragging");
72+
}
73+
74+
- (void)scrollViewDidScroll:(CCScrollView *)scrollView
75+
{
76+
//CCLOG(@"Scrolling");
77+
}
78+
5379
- (void)setupScrollViewPagingTest
5480
{
5581
self.subTitle = @"Paging - Pan the content layer it should snap into a 3 x 3 grid.";

cocos2d-ui/CCScrollView.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@
2525
#import "CCNode.h"
2626

2727
@class CCTapDownGestureRecognizer;
28+
@class CCScrollView;
29+
30+
@protocol CCScrollViewDelegate <NSObject>
31+
32+
@optional
33+
- (void)scrollViewDidScroll:(CCScrollView *)scrollView;
34+
- (void)scrollViewWillBeginDragging:(CCScrollView *)scrollView;
35+
- (void)scrollViewDidEndDragging:(CCScrollView * )scrollView willDecelerate:(BOOL)decelerate;
36+
- (void)scrollViewWillBeginDecelerating:(CCScrollView *)scrollView;
37+
- (void)scrollViewDidEndDecelerating:(CCScrollView *)scrollView;
38+
39+
@end
2840

2941
#ifdef __CC_PLATFORM_IOS
3042

@@ -52,6 +64,8 @@
5264
CGPoint _velocity;
5365
}
5466

67+
@property (nonatomic, weak) id<CCScrollViewDelegate> delegate;
68+
5569
@property (nonatomic,strong) CCNode* contentNode;
5670

5771
@property (nonatomic,assign) BOOL flipYCoordinates;

cocos2d-ui/CCScrollView.m

Lines changed: 126 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,18 @@ @interface CCMoveToX : CCActionInterval
9191
{
9292
float _endPosition;
9393
float _startPos;
94+
void (^block)(void);
9495
}
9596
@end
9697

9798
@implementation CCMoveToX
9899

99-
-(id) initWithDuration: (CCTime) t positionX: (float) p
100+
-(id) initWithDuration: (CCTime) t positionX: (float) p callback:(void(^)(void))callback
100101
{
101-
if( (self=[super initWithDuration: t]) )
102+
if( (self=[super initWithDuration: t]) ) {
102103
_endPosition = p;
104+
block = callback;
105+
}
103106
return self;
104107
}
105108

@@ -119,6 +122,7 @@ -(void) update: (CCTime) t
119122
float y = node.position.y;
120123

121124
node.position = ccp(x,y);
125+
block();
122126
}
123127
@end
124128

@@ -127,15 +131,18 @@ @interface CCMoveToY : CCActionInterval
127131
{
128132
float _endPosition;
129133
float _startPos;
134+
void (^block)(void);
130135
}
131136
@end
132137

133138
@implementation CCMoveToY
134139

135-
-(id) initWithDuration: (CCTime) t positionY: (float) p
140+
-(id) initWithDuration: (CCTime) t positionY: (float) p callback:(void(^)(void))callback
136141
{
137-
if( (self=[super initWithDuration: t]) )
142+
if( (self=[super initWithDuration: t]) ) {
138143
_endPosition = p;
144+
block = [callback copy];
145+
}
139146
return self;
140147
}
141148

@@ -155,14 +162,21 @@ -(void) update: (CCTime) t
155162
float x = node.position.x;
156163

157164
node.position = ccp(x,y);
165+
block();
158166
}
159167
@end
160168

161169

162170
#pragma mark -
163171
#pragma mark CCScrollView
164172

165-
@implementation CCScrollView
173+
@implementation CCScrollView {
174+
BOOL _decelerating;
175+
176+
#ifdef __CC_PLATFORM_MAC
177+
CGPoint _lastPosition;
178+
#endif
179+
}
166180

167181
#pragma mark Initializers
168182

@@ -335,31 +349,13 @@ - (void) setScrollPosition:(CGPoint)newPos
335349

336350
- (void) setScrollPosition:(CGPoint)newPos animated:(BOOL)animated
337351
{
352+
// Check bounds
353+
newPos.x = MAX(MIN(newPos.x, self.maxScrollX), self.minScrollX);
354+
newPos.y = MAX(MIN(newPos.y, self.maxScrollY), self.minScrollY);
355+
338356
BOOL xMoved = (newPos.x != self.scrollPosition.x);
339357
BOOL yMoved = (newPos.y != self.scrollPosition.y);
340-
341-
// Check bounds
342-
if (newPos.x > self.maxScrollX)
343-
{
344-
newPos.x = self.maxScrollX;
345-
xMoved = YES;
346-
}
347-
if (newPos.x < self.minScrollX)
348-
{
349-
newPos.x = self.minScrollX;
350-
xMoved = YES;
351-
}
352-
if (newPos.y > self.maxScrollY)
353-
{
354-
newPos.y = self.maxScrollY;
355-
yMoved = YES;
356-
}
357-
if (newPos.y < self.minScrollY)
358-
{
359-
newPos.y = self.minScrollY;
360-
yMoved = YES;
361-
}
362-
358+
363359
if (animated)
364360
{
365361
CGPoint oldPos = self.scrollPosition;
@@ -375,7 +371,9 @@ - (void) setScrollPosition:(CGPoint)newPos animated:(BOOL)animated
375371
_animatingX = YES;
376372

377373
// Create animation action
378-
CCActionInterval* action = [CCActionEaseOut actionWithAction:[[CCMoveToX alloc] initWithDuration:duration positionX:-newPos.x] rate:2];
374+
CCActionInterval* action = [CCActionEaseOut actionWithAction:[[CCMoveToX alloc] initWithDuration:duration positionX:-newPos.x callback:^{
375+
[self scrollViewDidScroll];
376+
}] rate:2];
379377
CCActionCallFunc* callFunc = [CCActionCallFunc actionWithTarget:self selector:@selector(xAnimationDone)];
380378
action = [CCActionSequence actions:action, callFunc, nil];
381379
action.tag = kCCScrollViewActionXTag;
@@ -389,7 +387,9 @@ - (void) setScrollPosition:(CGPoint)newPos animated:(BOOL)animated
389387
_animatingY = YES;
390388

391389
// Create animation action
392-
CCActionInterval* action = [CCActionEaseOut actionWithAction:[[CCMoveToY alloc] initWithDuration:duration positionY:-newPos.y] rate:2];
390+
CCActionInterval* action = [CCActionEaseOut actionWithAction:[[CCMoveToY alloc] initWithDuration:duration positionY:-newPos.y callback:^{
391+
[self scrollViewDidScroll];
392+
}] rate:2];
393393
CCActionCallFunc* callFunc = [CCActionCallFunc actionWithTarget:self selector:@selector(yAnimationDone)];
394394
action = [CCActionSequence actions:action, callFunc, nil];
395395
action.tag = kCCScrollViewActionYTag;
@@ -399,6 +399,9 @@ - (void) setScrollPosition:(CGPoint)newPos animated:(BOOL)animated
399399
}
400400
else
401401
{
402+
#ifdef __CC_PLATFORM_MAC
403+
_lastPosition = self.scrollPosition;
404+
#endif
402405
[_contentNode stopActionByTag:kCCScrollViewActionXTag];
403406
[_contentNode stopActionByTag:kCCScrollViewActionYTag];
404407
_contentNode.position = ccpMult(newPos, -1);
@@ -453,15 +456,32 @@ - (void) panLayerToTarget:(CGPoint) newPos
453456
if (newPos.y > self.maxScrollY) newPos.y = self.maxScrollY;
454457
if (newPos.y < self.minScrollY) newPos.y = self.minScrollY;
455458
}
456-
459+
[self scrollViewDidScroll];
457460
_contentNode.position = ccpMult(newPos, -1);
458461
}
459462

460463
- (void) update:(CCTime)df
461464
{
462465
float fps = 1.0/df;
463466
float p = 60/fps;
464-
467+
468+
if (! CGPointEqualToPoint(_velocity, CGPointZero) ) {
469+
[self scrollViewDidScroll];
470+
} else {
471+
472+
#ifdef __CC_PLATFORM_IOS
473+
if ( _decelerating && !(_animatingX || _animatingY)) {
474+
[self scrollViewDidEndDecelerating];
475+
_decelerating = NO;
476+
}
477+
#elif defined(__CC_PLATFORM_MAC)
478+
if ( _decelerating && CGPointEqualToPoint(_lastPosition, self.scrollPosition)) {
479+
[self scrollViewDidEndDecelerating];
480+
_decelerating = NO;
481+
}
482+
#endif
483+
}
484+
465485
if (!_isPanning)
466486
{
467487
if (_velocity.x != 0 || _velocity.y != 0)
@@ -553,6 +573,7 @@ - (void)handlePan:(UIGestureRecognizer *)gestureRecognizer
553573

554574
if (pgr.state == UIGestureRecognizerStateBegan)
555575
{
576+
[self scrollViewWillBeginDragging];
556577
_animatingX = NO;
557578
_animatingY = NO;
558579
_rawTranslationStart = rawTranslation;
@@ -581,6 +602,7 @@ - (void)handlePan:(UIGestureRecognizer *)gestureRecognizer
581602
}
582603
else if (pgr.state == UIGestureRecognizerStateEnded)
583604
{
605+
584606
// Calculate the velocity in node space
585607
CGPoint ref = [dir convertToGL:CGPointZero];
586608
ref = [self convertToNodeSpace:ref];
@@ -595,6 +617,7 @@ - (void)handlePan:(UIGestureRecognizer *)gestureRecognizer
595617
// Check if scroll directions has been disabled
596618
if (!_horizontalScrollEnabled) _velocity.x = 0;
597619
if (!_verticalScrollEnabled) _velocity.y = 0;
620+
[self scrollViewDidEndDraggingAndWillDecelerate:!CGPointEqualToPoint(_velocity, CGPointZero)];
598621

599622
// Setup a target if paging is enabled
600623
if (_pagingEnabled)
@@ -633,7 +656,8 @@ - (void)handlePan:(UIGestureRecognizer *)gestureRecognizer
633656

634657
_velocity = CGPointZero;
635658
}
636-
659+
[self scrollViewWillBeginDecelerating];
660+
_decelerating = YES;
637661
_isPanning = NO;
638662
}
639663
else if (pgr.state == UIGestureRecognizerStateCancelled)
@@ -749,11 +773,30 @@ - (void) onExitTransitionDidStart
749773

750774
- (void)scrollWheel:(NSEvent *)theEvent
751775
{
752-
CCDirector* dir = [CCDirector sharedDirector];
753-
776+
CCDirector* dir = [CCDirector sharedDirector];
777+
754778
float deltaX = theEvent.deltaX;
755779
float deltaY = theEvent.deltaY;
756-
780+
781+
[self scrollViewDidScroll];
782+
783+
switch (theEvent.phase) {
784+
case NSEventPhaseBegan:
785+
[self scrollViewWillBeginDragging];
786+
break;
787+
case NSEventPhaseEnded:
788+
//TODO: add logic to determine if it will decelerate
789+
[self scrollViewDidEndDraggingAndWillDecelerate:YES];
790+
_decelerating = YES;
791+
default:
792+
break;
793+
}
794+
795+
if (theEvent.momentumPhase == NSEventPhaseBegan)
796+
{
797+
[self scrollViewWillBeginDecelerating];
798+
}
799+
757800
// Calculate the delta in node space
758801
CGPoint ref = [dir convertToGL:CGPointZero];
759802
ref = [self convertToNodeSpace:ref];
@@ -768,6 +811,7 @@ - (void)scrollWheel:(NSEvent *)theEvent
768811
// Flip coordinates
769812
if (_flipYCoordinates) delta.y = -delta.y;
770813
delta.x = -delta.x;
814+
771815

772816
// Handle disabled x/y axis
773817
if (!_horizontalScrollEnabled) delta.x = 0;
@@ -818,10 +862,55 @@ - (void)scrollWheel:(NSEvent *)theEvent
818862
// Update scroll position
819863
CGPoint scrollPos = self.scrollPosition;
820864
scrollPos = ccpAdd(delta, scrollPos);
821-
self.scrollPosition = scrollPos;
865+
self.scrollPosition = scrollPos;
822866
}
823867
}
824868

825869
#endif
826870

871+
872+
#pragma mark - CCScrollViewDelegate Helpers
873+
874+
- (void)scrollViewDidScroll
875+
{
876+
if ( [self.delegate respondsToSelector:@selector(scrollViewDidScroll:)] )
877+
{
878+
[self.delegate scrollViewDidScroll:self];
879+
}
880+
}
881+
882+
- (void)scrollViewWillBeginDragging
883+
{
884+
if ( [self.delegate respondsToSelector:@selector(scrollViewWillBeginDragging:)])
885+
{
886+
[self.delegate scrollViewWillBeginDragging:self];
887+
}
888+
}
889+
- (void)scrollViewDidEndDraggingAndWillDecelerate:(BOOL)decelerate
890+
{
891+
if ([self.delegate respondsToSelector:@selector(scrollViewDidEndDragging:willDecelerate:)])
892+
{
893+
[self.delegate scrollViewDidEndDragging:self
894+
willDecelerate:decelerate];
895+
}
896+
}
897+
- (void)scrollViewWillBeginDecelerating
898+
{
899+
if ( !_pagingEnabled )
900+
{
901+
if ( [self.delegate respondsToSelector:@selector(scrollViewWillBeginDecelerating:)])
902+
{
903+
[self.delegate scrollViewWillBeginDecelerating:self];
904+
}
905+
}
906+
907+
}
908+
- (void)scrollViewDidEndDecelerating
909+
{
910+
if ( [self.delegate respondsToSelector:@selector(scrollViewDidEndDecelerating:)])
911+
{
912+
[self.delegate scrollViewDidEndDecelerating:self];
913+
}
914+
}
915+
827916
@end

0 commit comments

Comments
 (0)