Skip to content

Commit

Permalink
Use DragListener and DragListener.createForwardingListener, see #95
Browse files Browse the repository at this point in the history
  • Loading branch information
samreid committed Dec 19, 2024
1 parent 740aebe commit d798975
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 53 deletions.
53 changes: 11 additions & 42 deletions js/least-squares-regression/view/DataPointCreatorNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
* @author Martin Veillette (Berea College)
*/

import Vector2 from '../../../../dot/js/Vector2.js';
import ScreenView from '../../../../joist/js/ScreenView.js';
import ModelViewTransform2 from '../../../../phetcommon/js/view/ModelViewTransform2.js';
import { Circle, Node, NodeOptions, SceneryEvent, SimpleDragHandler } from '../../../../scenery/js/imports.js';
import { Circle, DragListener, Node, NodeOptions } from '../../../../scenery/js/imports.js';
import leastSquaresRegression from '../../leastSquaresRegression.js';
import LeastSquaresRegressionConstants from '../LeastSquaresRegressionConstants.js';
import DataPoint from '../model/DataPoint.js';
import DynamicDataPointNode from './DynamicDataPointNode.js';

export default class DataPointCreatorNode extends Node {

Expand All @@ -23,7 +22,7 @@ export default class DataPointCreatorNode extends Node {
* @param providedOptions - Optional customization options.
*/
public constructor(
addDataPointToModel: ( dataPoint: DataPoint ) => void,
addDataPointToModel: ( dataPoint: DataPoint ) => DynamicDataPointNode,
modelViewTransform: ModelViewTransform2,
providedOptions?: NodeOptions
) {
Expand All @@ -42,48 +41,18 @@ export default class DataPointCreatorNode extends Node {
this.touchArea = this.localBounds.dilated( 15 );
this.mouseArea = this.localBounds.dilated( 5 );

let parentScreenView: ScreenView | null = null;
let dataPoint: DataPoint | null = null;

// Add the listener that will allow the user to click on this and create a new dataPoint, then position it in the model.
this.addInputListener( new SimpleDragHandler( {

// Allow moving a finger (touch) across this node to interact with it
allowTouchSnag: true,

start: ( event: SceneryEvent ) => {

// find the parent screen if not already found by moving up the scene graph
if ( !parentScreenView ) {

let testNode = ( this as Node ) || null; // Workaround for lint errors for this alias
while ( testNode !== null ) {
if ( testNode instanceof ScreenView ) {
parentScreenView = testNode;
break;
}
testNode = testNode.parents[ 0 ]; // move up the scene graph by one level
}
assert && assert( parentScreenView, 'unable to find parent screen view' );
}

// Determine the initial position (set to be one circle radius above the pointer point)
const initialPosition = parentScreenView!.globalToLocalPoint( event.pointer.point.plus( new Vector2( 0, -LeastSquaresRegressionConstants.DYNAMIC_DATA_POINT_RADIUS ) ) );
this.addInputListener( DragListener.createForwardingListener( event => {

// Create and add the new model element.
dataPoint = new DataPoint( modelViewTransform.viewToModelPosition( initialPosition ) );
dataPoint.userControlledProperty.set( true );
addDataPointToModel( dataPoint );
},
// Determine the initial position (set to be one circle radius above the pointer point)
const initialPosition = event.pointer.point;

translate: ( translationParams: { delta: Vector2; oldPosition: Vector2; position: Vector2 } ) => {
dataPoint!.positionProperty.value = dataPoint!.positionProperty.value.plus( modelViewTransform.viewToModelDelta( translationParams.delta ) );
},
// Create and add the new model element.
const dataPoint = new DataPoint( modelViewTransform.viewToModelPosition( initialPosition ) );
dataPoint.userControlledProperty.set( true );
const dynamicDataPointNode = addDataPointToModel( dataPoint );

end: () => {
dataPoint!.userControlledProperty.set( false );
dataPoint = null;
}
dynamicDataPointNode.dragListener.press( event );
} ) );

// Pass options through to parent.
Expand Down
21 changes: 11 additions & 10 deletions js/least-squares-regression/view/DynamicDataPointNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@
* @author Martin Veillette (Berea College)
*/

import Vector2 from '../../../../dot/js/Vector2.js';
import ModelViewTransform2 from '../../../../phetcommon/js/view/ModelViewTransform2.js';
import { Circle, SimpleDragHandler } from '../../../../scenery/js/imports.js';
import { Circle, DragListener } from '../../../../scenery/js/imports.js';
import leastSquaresRegression from '../../leastSquaresRegression.js';
import LeastSquaresRegressionConstants from '../LeastSquaresRegressionConstants.js';
import DataPoint from '../model/DataPoint.js';
import DataPointNode from './DataPointNode.js';

export default class DynamicDataPointNode extends DataPointNode {
public readonly dragListener: DragListener;

public constructor( dataPoint: DataPoint, modelViewTransform: ModelViewTransform2 ) {
public constructor(

public readonly dataPoint: DataPoint, modelViewTransform: ModelViewTransform2 ) {

// Create the visual representation of the DynamicDataPoint
const representation = new Circle( LeastSquaresRegressionConstants.DYNAMIC_DATA_POINT_RADIUS, {
Expand All @@ -31,23 +33,22 @@ export default class DynamicDataPointNode extends DataPointNode {
this.touchArea = this.localBounds.dilatedXY( 15, 15 );

// Add the listener that will allow the user to drag the dataPoint around.
this.addInputListener( new SimpleDragHandler( {
this.dragListener = new DragListener( {
transform: modelViewTransform,
positionProperty: dataPoint.positionProperty,

// Allow moving a finger (touch) across a node to pick it up.
allowTouchSnag: true,

// Handler that moves the dataPoint in model space.
start: () => {
dataPoint.userControlledProperty.set( true );
},

translate: ( args: { delta: Vector2; oldPosition: Vector2; position: Vector2 } ) => {
dataPoint.positionProperty.value = modelViewTransform.viewToModelPosition( args.position );
},

end: () => {
dataPoint.userControlledProperty.set( false );
}
} ) );
} );
this.addInputListener( this.dragListener );
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,10 @@ export default class LeastSquaresRegressionScreenView extends ScreenView {
// Add the dataPoint creator nodes. These must be added on the backLayer but after the bucket hole for proper layering.
DATA_POINT_CREATOR_OFFSET_POSITIONS.forEach( offset => {
backLayer.addChild( new DataPointCreatorNode(
model.addUserCreatedDataPoint.bind( model ),
dataPoint => {
model.addUserCreatedDataPoint( dataPoint );
return dataPointsLayer.children.find( node => node instanceof DynamicDataPointNode && node.dataPoint === dataPoint ) as DynamicDataPointNode;
},
modelViewTransform, {
left: bucketHole.centerX + offset.x,
top: bucketHole.centerY + offset.y
Expand Down

0 comments on commit d798975

Please sign in to comment.