-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
consolidate code for forwarding events #639
Comments
Here is the related issue from Expression Exchange: phetsims/expression-exchange#121 |
How about: node.addInputListener( SimpleDragHandler.createForwardingListener( {
down: function( event ) {
// no need to check event.pointer.dragging or canStartPress here
},
touchSnag: {boolean}
// no need to do touchenter/touchmove here
} ) ); |
CircuitElementToolbox.js and SensorToolbox.js (the 2 toolboxes in circuit-construction-kit-common) have this pattern, you can search for
I'm not sure how that would work exactly--does it return a plain object or a SimpleDragHandler? If the former, then it seems like it would work OK but would be a bit odd that SimpleDragHandler.createSomething doesn't return a SimpleDragHandler. And we discussed a few days ago that SimpleDragHandler doesn't support multi-interaction. |
createForwardingListener: function( listener ) {
return {
down: function( event ) {
if ( !event.pointer.dragging && event.canStartPress() ) {
listener.down( event );
}
},
touchenter: function( event ) {
listener.touchSnag && listener.down( event );
},
touchmove: function( event ) {
listener.touchSnag && listener.down( event );
}
};
}
It's totally SimpleDragHandler-specific with the check for
Yup, it supports preventing it! |
Understood, thanks for clarifying, that sounds great! |
Touchenter and touchmove should be: touchenter: function( event ) {
dragHandler.touchSnag && this.down( event );
},
touchmove: function( event ) {
dragHandler.touchSnag && this.down( event );
} So they can short circuit. |
I added SimpleDragHandler.createForwardingListener in the preceding commit. I also separated out the |
Don't see it pushed to master (checked https://github.com/phetsims/scenery/blob/master/js/input/SimpleDragHandler.js). I only see the CCK commit. |
Sorry about the bug in my implementation! |
No problem, it should be pushed now. |
I'm unclear on how the addition of if ( createdCoinTermView ) {
// forward the event to the view node's drag handler
createdCoinTermView.dragHandler.startDrag( event );
} |
The pattern is changed. The old pattern was: this.addInputListener( {
down: function( event ) {
// ignore this if already dragging
if ( event.pointer.dragging ) { return; }
// don't try to start drags with a right mouse button or an attached pointer
if ( !event.canStartPress() ) { return; }
createSomething();
// forward the event to the view node's drag handler
{{something}}.dragHandler.startDrag( event );
},
// touch enters this node
touchenter: function( event ) {
this.down( event );
},
// touch moves over this node
touchmove: function( event ) {
this.down( event );
}
} ) The new pattern is: this.addInputListener( SimpleDragHandler.createForwardingListener( {
down: function( event ) {
createSomething();
{{something}}.dragHandler.startDrag(event);
}
}, {
allowTouchSnag: true
} ) ); Caveat and disclaimer: |
According to @jonathanolson via a Skype call: (1) He didn't review the implementation of
/**
* Creates an input listener that forwards events to the specified input listener
* See https://github.com/phetsims/scenery/issues/639
* @param {function(Event)} down - down function to be added to the input listener
* @param {Object} [options]
* @returns {Object} a scenery input listener
*/
createForwardingListener: function( down, options ) {
options = _.extend( {
allowTouchSnag: false
}, options );
return {
down: function( event ) {
if ( !event.pointer.dragging && event.canStartPress() ) {
down( event );
}
},
touchenter: function( event ) {
options.allowTouchSnag && this.down( event );
},
touchmove: function( event ) {
options.allowTouchSnag && this.down( event );
}
};
} @jonathanolson (if I understood) prefers (2) Use of // ignore this if already dragging
if ( event.pointer.dragging ) { return; }
// don't try to start drags with a right mouse button or an attached pointer
if ( !event.canStartPress() ) { return; } (3) This information needs to be folded into phetsims/scenery-phet#214. Other developers are looking to that issue for guidance about how to apply the creator pattern (phetsims/projectile-motion#20 (comment) being one of many examples). |
After thinking about it, I agree with not having the callback in options, and with the two parameters. @pixelzoom's changes look great to me, any objections @samreid? |
Those changes look great to me, thanks @pixelzoom! Since I have (the only?) code that uses |
I pushed the changes in the preceding 2 commits and they are working nicely. |
Reassigning to @pixelzoom for review. |
This specific code changes look good. But 2 remaining problems: (1) The way in which this information was folded into the recommend pattern (see phetsims/scenery-phet#214 (comment)) is insufficient, as I've noted in that issue. (2) This API works only if your input listener involves only @jonathanolson your thoughts on (2) ? |
We're unlikely to need something that works on up, but could create something when that need arises. Maybe we add a "down" qualifier to the function name? |
@andrea-phet is reviewing phetsims/scenery-phet#214, I'm not sure what else to do for this issue. @pixelzoom can you please advise? |
Remaining issues to address: (1) phetsims/scenery-phet#214 contains no code sample that summarizes how (2) It's unclear to me why (3) |
The "event.pointer.dragging" check is actually specific to SimpleDragHandler. Sorry I hadn't thought about it before, but once #218 is finished (i.e. SimpleDragHandler uses the Pointer attach API), then the "dragging" check would be unneeded, as the Thus once that's done, we CAN make the forwarding listener more general (so it would work for DragListener), and it would live in a different place (probably listeners/ForwardingListener in Scenery). Since this would generally be beneficial before we "standardize" a pattern, I'd like to look into doing this first.
That comment looks like I'm saying we won't need an "up" variety, not referencing other input listener types that aren't SimpleDragHandlers (since usually in the down callback, you need to create the object that will have a drag listener anyways). I'd like to hear more specifics about what type of generalization you mean. |
@pixelzoom and @jonathanolson I'll leave this up to you for now, but please invite me back if/when you need me. |
Approximately 2/3rds of simulations are erroring out when I make listeners "attach", since it then becomes an assertion failure to have the same pointer have two SimpleDragHandlers/DownUpListeners to listen to it at the same time. I'll need to look more into it later, it won't be an easy quick fix to be able to skip checking the SimpleDragHandler "dragging" flag. |
Sounds like @jonathanolson has something in mind in #639 (comment). Feel free to assign to me and @samreid for review when you're ready. |
We've been using a pattern for a while where a node in some sort of toolbox creates a new node and then forwards subsequent input events to the created node. There was recently a need to make touch snag work for this, and the code was implemented - and essentially duplicated - in CCK and Expression Exchange. This should be consolidated into a new object to avoid code duplication. The relevant code in CCK is in
CoinTermCreatorNode
, and currently looks like this:@samreid - can you note where this pattern was used in CCK, and then we can decide who will consolidate.
The text was updated successfully, but these errors were encountered: