diff --git a/cocos2d-tests.xcodeproj/project.pbxproj b/cocos2d-tests.xcodeproj/project.pbxproj index bd20f68a1d5..45e774f8d83 100644 --- a/cocos2d-tests.xcodeproj/project.pbxproj +++ b/cocos2d-tests.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 0E28FE1A197FCE4500F78989 /* CCCacheTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E28FE19197FCE4500F78989 /* CCCacheTest.m */; }; + 750B0BF01A7A936C00DC7048 /* CCActionsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 75F4EA241A69847C000E637B /* CCActionsTest.m */; }; 75556A04185636F100ED1B0F /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75556A03185636F100ED1B0F /* XCTest.framework */; }; 75556A05185636F100ED1B0F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B7E2605717E7D278007067F0 /* Foundation.framework */; }; 75556A15185636FB00ED1B0F /* powered.png in Resources */ = {isa = PBXBuildFile; fileRef = 755569E71856361100ED1B0F /* powered.png */; }; @@ -1404,14 +1405,15 @@ D3763D3819E734C5006C050D /* MainMenu.m in Sources */, D3763D3919E734C5006C050D /* TestBase.m in Sources */, D3763D3A19E734C5006C050D /* CCCacheTest.m in Sources */, + 750B0BF01A7A936C00DC7048 /* CCActionsTest.m in Sources */, D3763D3B19E734C5006C050D /* CCEffectsTest.m in Sources */, D3763D3C19E734C5006C050D /* CCRendererTest.m in Sources */, + D3763D4019E734C5006C050D /* CCTableViewTest.m in Sources */, 75C72C091A82AD7900814F60 /* main.m in Sources */, D3763D3D19E734C5006C050D /* SpritePerformanceTest.m in Sources */, D35C2D281A1BC83F00FF96B0 /* CCViewportNodeTest.m in Sources */, D3763D3E19E734C5006C050D /* CCScrollViewTest.m in Sources */, D3763D3F19E734C5006C050D /* CCSchedulerTest.m in Sources */, - D3763D4019E734C5006C050D /* CCTableViewTest.m in Sources */, D3763D4119E734C5006C050D /* CCTransitionTest.m in Sources */, D3763D4219E734C5006C050D /* CCResponderTest.m in Sources */, D3763D4319E734C5006C050D /* CCSprite9SliceTest.m in Sources */, diff --git a/cocos2d-ui/CCControl.m b/cocos2d-ui/CCControl.m index 98ae0a6175f..0aa2a3c0f85 100644 --- a/cocos2d-ui/CCControl.m +++ b/cocos2d-ui/CCControl.m @@ -150,16 +150,20 @@ - (void) touchUpOutside:(CCTouch*) touch withEvent:(CCTouchEvent*) event #elif __CC_PLATFORM_MAC -- (void) mouseDown:(NSEvent *)event +- (void) mouseDown:(NSEvent *)event button:(CCMouseButton)button { + if(button != CCMouseButtonLeft) return; + _tracking = YES; _touchInside = YES; [self mouseDownEntered:event]; } -- (void) mouseDragged:(NSEvent *)event +- (void) mouseDragged:(NSEvent *)event button:(CCMouseButton)button { + if(button != CCMouseButtonLeft) return; + if ([self clippedHitTestWithWorldPos:[event locationInWorld]]) { if (!_touchInside) @@ -178,14 +182,13 @@ - (void) mouseDragged:(NSEvent *)event } } -- (void) mouseUp:(NSEvent *)event +- (void) mouseUp:(NSEvent *)event button:(CCMouseButton)button { - if (_touchInside) - { + if(button != CCMouseButtonLeft) return; + + if (_touchInside) { [self mouseUpInside:event]; - } - else - { + } else { [self mouseUpOutside:event]; } diff --git a/cocos2d-ui/CCSlider.m b/cocos2d-ui/CCSlider.m index 220864dbc64..c7ddb97abde 100644 --- a/cocos2d-ui/CCSlider.m +++ b/cocos2d-ui/CCSlider.m @@ -133,13 +133,17 @@ - (void) mouseUpOutside:(NSEvent*)event [self inputUpOutside]; } -- (void) mouseDragged:(NSEvent*)event +- (void) mouseDragged:(NSEvent*)event button:(CCMouseButton) button { + if(button != CCMouseButtonLeft){ + return; + } + CGPoint dragPos = [event locationInNode:self]; [self inputDraggedWithPos:dragPos]; - [super mouseDragged:event]; + [super mouseDragged:event button: button]; } #endif diff --git a/cocos2d/CCResponder.h b/cocos2d/CCResponder.h index 3c365476dfc..1e323132de0 100644 --- a/cocos2d/CCResponder.h +++ b/cocos2d/CCResponder.h @@ -181,84 +181,59 @@ /// ----------------------------------------------------------------------- /** - * Called when left mouse button is pressed inside a node with userInteractionEnabled set to YES. - * - * @param theEvent The event created. - * @see [NSEvent](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/) - */ -- (void)mouseDown:(NSEvent *)theEvent; - -/** - * Called when left mouse button is held and mouse dragged for a node with userInteractionEnabled set to YES. - * - * @param theEvent The event created. - * @see [NSEvent](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/) + * Defines the various mouse buttons. */ -- (void)mouseDragged:(NSEvent *)theEvent; +typedef NS_ENUM(NSInteger, CCMouseButton) +{ + /** Defines left mouse button, in mouse events on OSX. */ + CCMouseButtonLeft, + + /** Defines right mouse button, in mouse events on OSX. */ + CCMouseButtonRight, + + /** Defines other (middle) mouse button, in mouse events on OSX. */ + CCMouseButtonOther, +}; /** - * Called when left mouse button is released for a node with userInteractionEnabled set to YES. + * Called when any mouse button is pressed inside a node with userInteractionEnabled set to YES. * * @param theEvent The event created. * @see [NSEvent](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/) */ -- (void)mouseUp:(NSEvent *)theEvent; +- (void)mouseDown:(NSEvent *)theEvent button:(CCMouseButton) button; /** - * Called when right mouse button is pressed inside a node with userInteractionEnabled set to YES. + * Called when any mouse button is held and mouse dragged for a node with userInteractionEnabled set to YES. * * @param theEvent The event created. * @see [NSEvent](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/) */ -- (void)rightMouseDown:(NSEvent *)theEvent; +- (void)mouseDragged:(NSEvent *)theEvent button:(CCMouseButton) button; /** - * Called when right mouse button is held and mouse dragged for a node with userInteractionEnabled set to YES. + * Called when any mouse button is released for a node with userInteractionEnabled set to YES. * * @param theEvent The event created. * @see [NSEvent](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/) */ -- (void)rightMouseDragged:(NSEvent *)theEvent; +- (void)mouseUp:(NSEvent *)theEvent button:(CCMouseButton) button; /** - * Called when right mouse button is released for a node with userInteractionEnabled set to YES. - * - * @param theEvent The event created. - * @see [NSEvent](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/) - */ -- (void)rightMouseUp:(NSEvent *)theEvent; - -/** - * Called when middle mouse button is pressed inside a node with userInteractionEnabled set to YES. - * - * @param theEvent The event created. - * @see [NSEvent](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/) - */ -- (void)otherMouseDown:(NSEvent *)theEvent; - -/** - * Called when middle mouse button is held and mouse dragged for a node with userInteractionEnabled set to YES. - * - * @param theEvent The event created. - * @see [NSEvent](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/) - */ -- (void)otherMouseDragged:(NSEvent *)theEvent; - -/** - * Called when middle mouse button is released for a node with userInteractionEnabled set to YES. + * Called when scroll wheel moved while mouse cursor is inside a node with userInteractionEnabled set to YES. * * @param theEvent The event created. * @see [NSEvent](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/) */ -- (void)otherMouseUp:(NSEvent *)theEvent; +- (void)scrollWheel:(NSEvent *)theEvent; /** - * Called when scroll wheel moved while mouse cursor is inside a node with userInteractionEnabled set to YES. - * - * @param theEvent The event created. - * @see [NSEvent](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/) + Called when the mouse is moved. + + @see [NSEvent](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/) + @since v4.0 */ -- (void)scrollWheel:(NSEvent *)theEvent; +- (void)mouseMoved:(NSEvent *)theEvent; /** * Called whan a key down. diff --git a/cocos2d/CCResponder.m b/cocos2d/CCResponder.m index fe85182ddff..904d6887cc3 100644 --- a/cocos2d/CCResponder.m +++ b/cocos2d/CCResponder.m @@ -109,64 +109,39 @@ - (void)touchCancelled:(CCTouch *)touch withEvent:(CCTouchEvent *)event #pragma mark - OSX // ----------------------------------------------------------------- -- (void)mouseDown:(NSEvent *)theEvent +- (void)mouseDown:(NSEvent *)theEvent button:(CCMouseButton) button { [[CCDirector currentDirector].responderManager discardCurrentEvent]; } -- (void)mouseDragged:(NSEvent *)theEvent +- (void)mouseDragged:(NSEvent *)theEvent button:(CCMouseButton) button { [[CCDirector currentDirector].responderManager discardCurrentEvent]; } -- (void)mouseUp:(NSEvent *)theEvent +- (void)mouseUp:(NSEvent *)theEvent button:(CCMouseButton) button { [[CCDirector currentDirector].responderManager discardCurrentEvent]; } -- (void)rightMouseDown:(NSEvent *)theEvent -{ - [[CCDirector currentDirector].responderManager discardCurrentEvent]; -} - -- (void)rightMouseDragged:(NSEvent *)theEvent -{ - [[CCDirector currentDirector].responderManager discardCurrentEvent]; -} - -- (void)rightMouseUp:(NSEvent *)theEvent -{ - [[CCDirector currentDirector].responderManager discardCurrentEvent]; -} - -- (void)otherMouseDown:(NSEvent *)theEvent -{ - [[CCDirector currentDirector].responderManager discardCurrentEvent]; -} - -- (void)otherMouseDragged:(NSEvent *)theEvent -{ - [[CCDirector currentDirector].responderManager discardCurrentEvent]; -} - -- (void)otherMouseUp:(NSEvent *)theEvent +- (void)scrollWheel:(NSEvent *)theEvent { [[CCDirector currentDirector].responderManager discardCurrentEvent]; } -- (void)scrollWheel:(NSEvent *)theEvent +- (void)mouseMoved:(NSEvent *)theEvent { [[CCDirector currentDirector].responderManager discardCurrentEvent]; } -(void)keyDown:(NSEvent *)theEvent { - [[CCDirector currentDirector].responderManager discardCurrentEvent]; + [[CCDirector currentDirector].responderManager discardCurrentEvent]; } -(void)keyUp:(NSEvent *)theEvent { - [[CCDirector currentDirector].responderManager discardCurrentEvent]; + [[CCDirector currentDirector].responderManager discardCurrentEvent]; } #endif diff --git a/cocos2d/CCResponderManager.h b/cocos2d/CCResponderManager.h index a24377e0f5f..de0cbba2e9b 100644 --- a/cocos2d/CCResponderManager.h +++ b/cocos2d/CCResponderManager.h @@ -31,6 +31,7 @@ // TODO: Grab mouse and touch by implementing onPressed, onReleased, onClicked #import "ccTypes.h" +#import "CCResponder.h" @class CCTouch; @class CCTouchEvent; @@ -64,23 +65,6 @@ #elif __CC_PLATFORM_MAC -#pragma mark - OSX Running Responder - -/** - * Defines the various mouse buttons. - */ -typedef NS_ENUM(NSInteger, CCMouseButton) -{ - /** Defines left mouse button, in mouse events on OSX. */ - CCMouseButtonLeft, - - /** Defines right mouse button, in mouse events on OSX. */ - CCMouseButtonRight, - - /** Defines other (middle) mouse button, in mouse events on OSX. */ - CCMouseButtonOther, -}; - #pragma mark - CCRunningResponder /** diff --git a/cocos2d/CCResponderManager.m b/cocos2d/CCResponderManager.m index 6da1a4b81ea..413cbbb1455 100644 --- a/cocos2d/CCResponderManager.m +++ b/cocos2d/CCResponderManager.m @@ -451,120 +451,43 @@ - (void)cancelResponder:(CCRunningResponder *)responder - (void)mouseDown:(NSEvent *)theEvent button:(CCMouseButton)button { if (!_enabled) return; - [_director.view.window makeFirstResponder:_director.view]; - if (_dirty) [self buildResponderList]; - [CCDirector pushCurrentDirector:_director]; - - // scan backwards through mouse responders - for (int index = _responderListCount - 1; index >= 0; index --) - { - CCNode *node = _responderList[index]; - - // check for hit test - if ([node clippedHitTestWithWorldPos:[_director convertEventToGL:theEvent]]) - { - // begin the mouse down - _currentEventProcessed = YES; - switch (button) - { - case CCMouseButtonLeft: if ([node respondsToSelector:@selector(mouseDown:)]) [node mouseDown:theEvent]; break; - case CCMouseButtonRight: if ([node respondsToSelector:@selector(rightMouseDown:)]) [node rightMouseDown:theEvent]; break; - case CCMouseButtonOther: if ([node respondsToSelector:@selector(otherMouseDown:)]) [node otherMouseDown:theEvent]; break; - } - - // if mouse was processed, remember it and break - if (_currentEventProcessed) - { - [self addResponder:node withButton:button]; - break; - } + [self executeOnEachResponder:^(CCNode *node){ + [node mouseDown:theEvent button:button]; + if (_currentEventProcessed) { + [self addResponder:node withButton:button]; } - } - [CCDirector popCurrentDirector]; + } withEvent:theEvent]; } -// TODO: Should all mouse buttons call mouseDragged? -// As it is now, only mouseDragged gets called if several buttons are pressed - - (void)mouseDragged:(NSEvent *)theEvent button:(CCMouseButton)button { + if (!_enabled) return; if (_dirty) [self buildResponderList]; CCRunningResponder *responder = [self responderForButton:button]; - if (responder) - { + if (responder) { + // This drag event is already associated with a specific target. CCNode *node = (CCNode *)responder.target; - [CCDirector pushCurrentDirector:_director]; - - // check if it locks mouse - if (node.claimsUserInteraction) - { - // move the mouse - switch (button) - { - case CCMouseButtonLeft: if ([node respondsToSelector:@selector(mouseDragged:)]) [node mouseDragged:theEvent]; break; - case CCMouseButtonRight: if ([node respondsToSelector:@selector(rightMouseDragged:)]) [node rightMouseDragged:theEvent]; break; - case CCMouseButtonOther: if ([node respondsToSelector:@selector(otherMouseDragged:)]) [node otherMouseDragged:theEvent]; break; - } - } - else - { - // as node does not lock mouse, check if it was moved outside - if (![node clippedHitTestWithWorldPos:[_director convertEventToGL:theEvent]]) - { - [_runningResponderList removeObject:responder]; - } - else - { - // move the mouse - switch (button) - { - case CCMouseButtonLeft: if ([node respondsToSelector:@selector(mouseDragged:)]) [node mouseDragged:theEvent]; break; - case CCMouseButtonRight: if ([node respondsToSelector:@selector(rightMouseDragged:)]) [node rightMouseDragged:theEvent]; break; - case CCMouseButtonOther: if ([node respondsToSelector:@selector(otherMouseDragged:)]) [node otherMouseDragged:theEvent]; break; - } - } - } - [CCDirector popCurrentDirector]; - - } - else - { - [CCDirector pushCurrentDirector:_director]; - - // scan backwards through mouse responders - for (int index = _responderListCount - 1; index >= 0; index --) - { - CCNode *node = _responderList[index]; - - // if the mouse responder does not lock mouse, it will receive a mouseDown if mouse is moved inside - if (!node.claimsUserInteraction && [node clippedHitTestWithWorldPos:[_director convertEventToGL:theEvent]]) - { - // begin the mouse down - _currentEventProcessed = YES; - - switch (button) - { - case CCMouseButtonLeft: if ([node respondsToSelector:@selector(mouseDown:)]) [node mouseDown:theEvent]; break; - case CCMouseButtonRight: if ([node respondsToSelector:@selector(rightMouseDown:)]) [node rightMouseDown:theEvent]; break; - case CCMouseButtonOther: if ([node respondsToSelector:@selector(otherMouseDown:)]) [node otherMouseDown:theEvent]; break; - } - - // if mouse was accepted, add it and break - if (_currentEventProcessed) - { - [self addResponder:node withButton:button]; - break; - } + // Items that claim user interaction receive events even if they occur outside of the bounds of the object. + if (node.claimsUserInteraction || [node clippedHitTestWithWorldPos:[_director convertEventToGL:theEvent]]) { + [CCDirector pushCurrentDirector:_director]; + if ([node respondsToSelector:@selector(mouseDragged:button:)]) [node mouseDragged:theEvent button:button]; + [CCDirector popCurrentDirector]; + } else { + [_runningResponderList removeObject:responder]; + } + } else { + [self executeOnEachResponder:^(CCNode *node){ + [node mouseDragged:theEvent button:button]; + if (_currentEventProcessed) { + [self addResponder:node withButton:button]; } - } - [CCDirector popCurrentDirector]; - + } withEvent:theEvent]; } } @@ -578,15 +501,9 @@ - (void)mouseUp:(NSEvent *)theEvent button:(CCMouseButton)button CCNode *node = (CCNode *)responder.target; [CCDirector pushCurrentDirector:_director]; - // end the mouse - switch (button) - { - case CCMouseButtonLeft: if ([node respondsToSelector:@selector(mouseUp:)]) [node mouseUp:theEvent]; break; - case CCMouseButtonRight: if ([node respondsToSelector:@selector(rightMouseUp:)]) [node rightMouseUp:theEvent]; break; - case CCMouseButtonOther: if ([node respondsToSelector:@selector(otherMouseUp:)]) [node otherMouseUp:theEvent]; break; - } + if ([node respondsToSelector:@selector(mouseUp:button:)]) [node mouseUp:theEvent button:button]; [CCDirector popCurrentDirector]; - // remove + [_runningResponderList removeObject:responder]; } } @@ -600,19 +517,38 @@ - (void)scrollWheel:(NSEvent *)theEvent // otherwise, scrollWheel goes to the node under the cursor CCRunningResponder *responder = [self responderForButton:CCMouseButtonOther]; - [CCDirector pushCurrentDirector:_director]; - if (responder) { CCNode *node = (CCNode *)responder.target; _currentEventProcessed = YES; + [CCDirector pushCurrentDirector:_director]; if ([node respondsToSelector:@selector(scrollWheel:)]) [node scrollWheel:theEvent]; - + [CCDirector popCurrentDirector]; + // if mouse was accepted, return if (_currentEventProcessed) return; } + [self executeOnEachResponder:^(CCNode *node){ + [node scrollWheel:theEvent]; + } withEvent:theEvent]; + +} + +- (void)mouseMoved:(NSEvent *)theEvent +{ + if (!_enabled) return; + if (_dirty) [self buildResponderList]; + + [self executeOnEachResponder:^(CCNode *node){ + [node mouseMoved:theEvent]; + } withEvent:theEvent]; +} + +- (void) executeOnEachResponder:(void(^)(CCNode *))block withEvent:(NSEvent *)theEvent +{ + [CCDirector pushCurrentDirector:_director]; // scan through responders, and find first one for (int index = _responderListCount - 1; index >= 0; index --) @@ -623,14 +559,13 @@ - (void)scrollWheel:(NSEvent *)theEvent if ([node clippedHitTestWithWorldPos:[_director convertEventToGL:theEvent]]) { _currentEventProcessed = YES; - if ([node respondsToSelector:@selector(scrollWheel:)]) [node scrollWheel:theEvent]; - + block(node); + // if mouse was accepted, break if (_currentEventProcessed) break; } } [CCDirector popCurrentDirector]; - } #pragma mark - Mac keyboard handling - @@ -638,7 +573,6 @@ - (void)scrollWheel:(NSEvent *)theEvent - (void)keyDown:(NSEvent *)theEvent { if (!_enabled) return; - // [[CCDirector currentDirector].view.window makeFirstResponder:[CCDirector currentDirector].view]; if (_dirty) [self buildResponderList]; [CCDirector pushCurrentDirector:_director]; @@ -655,12 +589,10 @@ - (void)keyDown:(NSEvent *)theEvent - (void)keyUp:(NSEvent *)theEvent { if (!_enabled) return; - // [[CCDirector currentDirector].view.window makeFirstResponder:[CCDirector currentDirector].view]; if (_dirty) [self buildResponderList]; [CCDirector pushCurrentDirector:_director]; - // scan backwards through mouse responders for (int index = _responderListCount - 1; index >= 0; index --) { CCNode *node = _responderList[index];