diff --git a/js/least-squares-regression/view/DataPointCreatorNode.ts b/js/least-squares-regression/view/DataPointCreatorNode.ts index affe879..ff0c6b5 100644 --- a/js/least-squares-regression/view/DataPointCreatorNode.ts +++ b/js/least-squares-regression/view/DataPointCreatorNode.ts @@ -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 { @@ -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 ) { @@ -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. diff --git a/js/least-squares-regression/view/DynamicDataPointNode.ts b/js/least-squares-regression/view/DynamicDataPointNode.ts index 06ad547..9d01bcb 100644 --- a/js/least-squares-regression/view/DynamicDataPointNode.ts +++ b/js/least-squares-regression/view/DynamicDataPointNode.ts @@ -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, { @@ -31,7 +33,10 @@ 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, @@ -39,15 +44,11 @@ export default class DynamicDataPointNode extends DataPointNode { 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 ); } } diff --git a/js/least-squares-regression/view/LeastSquaresRegressionScreenView.ts b/js/least-squares-regression/view/LeastSquaresRegressionScreenView.ts index 58cc7b1..e038800 100644 --- a/js/least-squares-regression/view/LeastSquaresRegressionScreenView.ts +++ b/js/least-squares-regression/view/LeastSquaresRegressionScreenView.ts @@ -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