Skip to content

Commit 0ff5020

Browse files
committed
Merge pull request #9 from spritebuilder/headless-develop
Android fixes (sliders, and scrolling, suspend/resume)
2 parents b484bf7 + 1b95df5 commit 0ff5020

File tree

9 files changed

+140
-27
lines changed

9 files changed

+140
-27
lines changed

cocos2d-ui/CCScrollView.m

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
#pragma mark -
6262
#pragma mark Helper classes
6363

64-
6564
#if __CC_PLATFORM_IOS
6665
@interface CCTapDownGestureRecognizer : UIGestureRecognizer
6766
@end
@@ -172,6 +171,7 @@ @implementation CCScrollView {
172171
#elif __CC_PLATFORM_ANDROID
173172
CCGestureListener *_listener;
174173
AndroidGestureDetector *_detector;
174+
CGPoint _rawScrollTranslation;
175175
#endif
176176
}
177177

@@ -214,7 +214,6 @@ - (id) initWithContentNode:(CCNode*)contentNode
214214
_listener = [[CCGestureListener alloc] init];
215215
_listener.delegate = (id<CCGestureListenerDelegate>)self;
216216
_detector = [[AndroidGestureDetector alloc] initWithContext:[CCActivity currentActivity] listener:_listener];
217-
[[[CCDirector sharedDirector] view] addGestureDetector:_detector];
218217
});
219218
#elif __CC_PLATFORM_MAC
220219

@@ -355,6 +354,8 @@ - (void) setScrollPosition:(CGPoint)newPos animated:(BOOL)animated
355354
newPos.x = MAX(MIN(newPos.x, self.maxScrollX), self.minScrollX);
356355
newPos.y = MAX(MIN(newPos.y, self.maxScrollY), self.minScrollY);
357356

357+
[self updateAndroidScrollTranslation:newPos];
358+
358359
BOOL xMoved = (newPos.x != self.scrollPosition.x);
359360
BOOL yMoved = (newPos.y != self.scrollPosition.y);
360361

@@ -409,6 +410,14 @@ - (void) setScrollPosition:(CGPoint)newPos animated:(BOOL)animated
409410
}
410411
}
411412

413+
- (void)updateAndroidScrollTranslation:(CGPoint)worldPosition
414+
{
415+
#if __CC_PLATFORM_ANDROID
416+
_rawScrollTranslation = [self convertToWindowSpace:worldPosition];
417+
#endif
418+
}
419+
420+
412421
- (void) xAnimationDone
413422
{
414423
_animatingX = NO;
@@ -492,6 +501,8 @@ - (void) update:(CCTime)df
492501

493502
_contentNode.position = ccpAdd(_contentNode.position, delta);
494503

504+
[self updateAndroidScrollTranslation:CGPointMake(_contentNode.position.x, _contentNode.position.y * -1)];
505+
495506
// Deaccelerate layer
496507
float deaccelerationX = kCCScrollViewDeacceleration;
497508
float deaccelerationY = kCCScrollViewDeacceleration;
@@ -740,8 +751,11 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecogni
740751
return (otherGestureRecognizer == _panRecognizer || otherGestureRecognizer == _tapRecognizer);
741752
}
742753

754+
#elif __CC_PLATFORM_ANDROID
755+
743756
- (void) onEnterTransitionDidFinish
744757
{
758+
#if __CC_PLATFORM_IOS
745759
// Add recognizers to view
746760
UIView* view = [CCDirector sharedDirector].view;
747761

@@ -751,12 +765,22 @@ - (void) onEnterTransitionDidFinish
751765
[recognizers insertObject:_tapRecognizer atIndex:0];
752766

753767
view.gestureRecognizers = recognizers;
754-
768+
#elif __CC_PLATFORM_ANDROID
769+
dispatch_async(dispatch_get_main_queue(), ^{
770+
if(_detector)
771+
{
772+
[[[CCDirector sharedDirector] view] addGestureDetector:_detector];
773+
}
774+
});
775+
#endif
755776
[super onEnterTransitionDidFinish];
756777
}
757778

779+
780+
758781
- (void) onExitTransitionDidStart
759782
{
783+
#if __CC_PLATFORM_IOS
760784
// Remove recognizers from view
761785
UIView* view = [CCDirector sharedDirector].view;
762786

@@ -765,11 +789,19 @@ - (void) onExitTransitionDidStart
765789
[recognizers removeObject:_tapRecognizer];
766790

767791
view.gestureRecognizers = recognizers;
792+
#elif __CC_PLATFORM_ANDROID
793+
dispatch_async(dispatch_get_main_queue(), ^{
794+
if(_detector)
795+
{
796+
[[[CCDirector sharedDirector] view] removeGestureDetector:_detector];
797+
}
798+
});
799+
#endif
768800

769801
[super onExitTransitionDidStart];
770802
}
771803

772-
#elif __CC_PLATFORM_ANDROID
804+
773805

774806
- (CCTouchPhase)handleGestureEvent:(AndroidMotionEvent *)start end:(AndroidMotionEvent *)end
775807
{
@@ -820,24 +852,23 @@ - (BOOL)onScroll:(AndroidMotionEvent *)start end:(AndroidMotionEvent *)end dista
820852
_velocity = CGPointZero;
821853

822854
// Note about start and end events: We will get a CCTouchPhaseBegan for the start event, followed by CCTouchPhaseMoved in the end event
823-
static CGPoint rawTranslation;
824855
CCTouchPhase phase = [self handleGestureEvent:start end:end];
825856

826857
if(phase == CCTouchPhaseCancelled || phase == CCTouchPhaseEnded)
827-
rawTranslation = CGPointMake(0.0f, 0.0f);
858+
_rawScrollTranslation = CGPointMake(0.0f, 0.0f);
828859

829860
float scaleFactor = [[CCDirector sharedDirector] view].contentScaleFactor;
830861

831862
dx /= scaleFactor;
832863
dy /= scaleFactor;
833864

834-
rawTranslation.x += dx;
835-
rawTranslation.y -= dy;
865+
_rawScrollTranslation.x += dx;
866+
_rawScrollTranslation.y -= dy;
836867

837868
CCDirector* dir = [CCDirector sharedDirector];
838869
[[CCActivity currentActivity] runOnGameThread:^{
839870

840-
CGPoint translation = [dir convertToGL:rawTranslation];
871+
CGPoint translation = [dir convertToGL:_rawScrollTranslation];
841872
translation = [self convertToNodeSpace:translation];
842873

843874
if (phase == CCTouchPhaseBegan)
@@ -868,6 +899,7 @@ - (BOOL)onScroll:(AndroidMotionEvent *)start end:(AndroidMotionEvent *)end dista
868899

869900
// Update position
870901
[self panLayerToTarget:newPos];
902+
871903
}
872904
else if (phase == CCTouchPhaseEnded)
873905
{
@@ -891,7 +923,7 @@ - (BOOL)onFling:(AndroidMotionEvent *)start end:(AndroidMotionEvent *)end veloci
891923
static CGPoint rawTranslationFling;
892924

893925
CCTouchPhase phase = [self handleGestureEvent:start end:end];
894-
926+
895927
if(phase == CCTouchPhaseCancelled || phase == CCTouchPhaseEnded)
896928
rawTranslationFling = CGPointMake(0.0f, 0.0f);
897929

@@ -918,9 +950,6 @@ - (BOOL)onFling:(AndroidMotionEvent *)start end:(AndroidMotionEvent *)end veloci
918950
CCDirector* dir = [CCDirector sharedDirector];
919951
[[CCActivity currentActivity] runOnGameThread:^{
920952

921-
CCResponderManager *mgr = [[CCDirector sharedDirector] responderManager];
922-
[mgr removeAllResponders];
923-
924953
CGPoint translation = [dir convertToGL:rawTranslationFling];
925954
translation = [self convertToNodeSpace:translation];
926955

cocos2d-ui/CCSlider.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ - (void) updateSliderPositionFromValue
7171
_handle.position = ccp(size.width * _sliderValue, size.height/2.0f);
7272
}
7373

74-
#if __CC_PLATFORM_IOS
74+
#if __CC_PLATFORM_IOS || __CC_PLATFORM_ANDROID
7575

7676
#pragma mark Handle touches
7777

cocos2d/CCDirector.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ -(void) resume
740740
{
741741
if( ! _isPaused )
742742
return;
743-
743+
744744
[self setAnimationInterval: _oldAnimationInterval];
745745

746746
if( gettimeofday( &_lastUpdate, NULL) != 0 ) {

cocos2d/CCNode.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,16 @@ A common user pattern in building a Cocos2d game is to subclass CCNode, add it t
615615
*/
616616
- (CGPoint)convertToWorldSpaceAR:(CGPoint)nodePoint;
617617

618+
/**
619+
* Converts a local Point to Window space coordinates.The result is in Points.
620+
* Treats the returned/received node point as anchor relative.
621+
*
622+
* @param nodePoint Local position in points.
623+
*
624+
* @return UI position in points.
625+
*/
626+
- (CGPoint)convertToWindowSpace:(CGPoint)nodePoint;
627+
618628

619629
/// -----------------------------------------------------------------------
620630
/// @name Rendering (Used by Subclasses)

cocos2d/Platforms/Android/CCActivity.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ BRIDGE_CLASS("org.cocos2d.CCActivity")
2424

2525
- (void)onDestroy;
2626

27+
- (void)onPause;
28+
- (void)onResume;
29+
2730
- (void)onLowMemory;
2831

2932
- (void)surfaceChanged:(JavaObject<AndroidSurfaceHolder> *)holder format:(int)format width:(int)width height:(int)height;

cocos2d/Platforms/Android/CCActivity.m

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ @implementation CCActivity {
5151

5252
@bridge (callback) run = run;
5353
@bridge (callback) onDestroy = onDestroy;
54+
@bridge (callback) onPause = onPause;
55+
@bridge (callback) onResume = onResume;
5456
@bridge (callback) onLowMemory = onLowMemory;
5557
@bridge (callback) surfaceCreated: = surfaceCreated;
5658
@bridge (callback) surfaceDestroyed: = surfaceDestroyed;
@@ -114,13 +116,77 @@ - (void)run
114116

115117
- (void)onDestroy
116118
{
119+
[[CCDirector sharedDirector] end];
117120
[super onDestroy];
118121
exit(0);
119122
}
120123

124+
- (void)onResume
125+
{
126+
#if USE_MAIN_THREAD
127+
[self resume];
128+
#else
129+
if(_thread == nil)
130+
{
131+
[super onResume];
132+
return;
133+
}
134+
135+
[self performSelector:@selector(resume) onThread:_thread withObject:nil waitUntilDone:YES modes:@[NSDefaultRunLoopMode]];
136+
#endif
137+
138+
[super onResume];
139+
}
140+
141+
- (void)resume
142+
{
143+
[[CCDirector sharedDirector] setNextDeltaTimeZero:YES];
144+
[[CCDirector sharedDirector] resume];
145+
}
146+
147+
- (void)onPause
148+
{
149+
#if USE_MAIN_THREAD
150+
[self pause];
151+
#else
152+
if(_thread == nil)
153+
{
154+
[super onPause];
155+
return;
156+
}
157+
158+
[self performSelector:@selector(pause) onThread:_thread withObject:nil waitUntilDone:YES modes:@[NSDefaultRunLoopMode]];
159+
#endif
160+
161+
[super onPause];
162+
}
163+
164+
- (void)pause
165+
{
166+
[[CCDirector sharedDirector] pause];
167+
}
168+
169+
121170
- (void)onLowMemory
122171
{
123-
// TODO: do something sensible here
172+
#if USE_MAIN_THREAD
173+
[self purgeChaceData];
174+
#else
175+
if(_thread == nil)
176+
{
177+
[super onLowMemory];
178+
return;
179+
}
180+
181+
[self performSelector:@selector(purgeChaceData) onThread:_thread withObject:nil waitUntilDone:YES modes:@[NSDefaultRunLoopMode]];
182+
#endif
183+
184+
[super onLowMemory];
185+
}
186+
187+
- (void)purgeChaceData
188+
{
189+
[[CCDirector sharedDirector] purgeCachedData];
124190
}
125191

126192
- (void)reshape:(NSValue *)value
@@ -157,6 +223,7 @@ - (void)setupPaths
157223
- (void)startGL:(JavaObject<AndroidSurfaceHolder> *)holder
158224
{
159225
@autoreleasepool {
226+
160227
_gameLoop = [NSRunLoop currentRunLoop];
161228

162229
[self setupView:holder];
@@ -181,6 +248,7 @@ - (void)startGL:(JavaObject<AndroidSurfaceHolder> *)holder
181248
[director setProjection:CCDirectorProjectionCustom];
182249
}
183250

251+
184252
[director runWithScene:[self startScene]];
185253
[director setAnimationInterval:1.0/60.0];
186254
[director startAnimation];
@@ -241,15 +309,13 @@ - (void)surfaceCreated:(JavaObject<AndroidSurfaceHolder> *)holder
241309

242310
- (void)surfaceDestroyed:(JavaObject<AndroidSurfaceHolder> *)holder
243311
{
244-
CCDirectorAndroid *director = (CCDirectorAndroid*)[CCDirector sharedDirector];
245312
#if USE_MAIN_THREAD
246-
[director stopAnimation];
313+
[self finish];
247314
#else
248-
[director performSelector:@selector(stopAnimation) onThread:_thread withObject:nil waitUntilDone:NO modes:@[NSDefaultRunLoopMode]];
315+
[self performSelector:@selector(finish) onThread:_thread withObject:nil waitUntilDone:NO modes:@[NSDefaultRunLoopMode]];
249316
#endif
250317
}
251318

252-
253319
- (BOOL)onKeyDown:(int32_t)keyCode keyEvent:(AndroidKeyEvent *)event
254320
{
255321
return NO;

cocos2d/Platforms/Android/CCDirectorAndroid.m

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,7 @@ - (void) stopAnimation
230230
return;
231231

232232
CCLOG(@"cocos2d: animation stopped");
233-
234-
[_runningThread cancel];
235-
// [_runningThread release];
236-
_runningThread = nil;
237-
233+
238234
[_displayLink invalidate];
239235
_displayLink = nil;
240236
_animating = NO;

cocos2d/Platforms/Android/CCGLView.m

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@ - (BOOL)onTouchEvent:(AndroidMotionEvent *)event
6767
{
6868
assert(pthread_main_np());
6969
@autoreleasepool {
70+
BOOL cancelTouch = NO;
7071
for (AndroidGestureDetector *detector in _gestureDetectors) {
71-
[detector onTouchEvent:event];
72+
cancelTouch = [detector onTouchEvent:event];
7273
}
7374

75+
7476
static dispatch_once_t once = 0L;
7577
dispatch_once(&once, ^{
7678
touches = [[NSMutableDictionary alloc] init];
@@ -98,6 +100,11 @@ - (BOOL)onTouchEvent:(AndroidMotionEvent *)event
98100
return NO;
99101
}
100102

103+
if(cancelTouch)
104+
{
105+
phase = CCTouchPhaseCancelled;
106+
}
107+
101108
NSTimeInterval timestamp = event.eventTime * 1000.0;
102109
currentEvent.timestamp = timestamp;
103110
NSMutableSet *eventTouches = [NSMutableSet set];

cocos2d/Platforms/Android/java/org/cocos2d/CCActivity.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ protected void onCreate(final Bundle savedInstanceState) {
3030

3131
public native void runLoop();
3232
public native void run();
33-
33+
3434
public native void onDestroy();
35+
public native void onResume();
36+
public native void onPause();
3537

3638
public native void onLowMemory();
3739

0 commit comments

Comments
 (0)