Skip to content

Commit

Permalink
change Ruler.positionProperty and GORulerNode.dragBoundsProperty to b…
Browse files Browse the repository at this point in the history
…e in model coordinates, #263
  • Loading branch information
pixelzoom committed Dec 13, 2021
1 parent dc483b9 commit 35d9e75
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 24 deletions.
3 changes: 1 addition & 2 deletions js/common/model/GORuler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ class GORuler {
private readonly orientation: RulerOrientation;
readonly isVertical: boolean;

// position of the ruler, in view coordinates!
//TODO change this to model coordinates, for phet-io. will also have to change dragBounds to model coordinates in view
// position of the ruler, in cm
readonly positionProperty: Property<Vector2>;

// length of the ruler, in cm
Expand Down
35 changes: 20 additions & 15 deletions js/common/view/GORulerNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class GORulerNode extends Node {
//TODO https://github.com/phetsims/geometric-optics/issues/133 this listener also depends on zoomTransformProperty, so there's a problematic ordering dependency there
zoomScaleProperty.link( zoomScale => {

// update model length, so that view length remains the same
// update ruler size, so that view size remains the same
ruler.scaleLength( zoomScale );

// update view
Expand All @@ -98,36 +98,35 @@ class GORulerNode extends Node {
} );

ruler.positionProperty.link( position => {
const viewPosition = zoomTransformProperty.value.modelToViewPosition( position );
if ( this.ruler.isVertical ) {
this.leftBottom = position;
this.leftBottom = viewPosition;
}
else {
this.leftTop = position;
this.leftTop = viewPosition;
}
} );

// Drag bounds for the ruler, to keep some part of the ruler inside the visible bounds of the ScreenView.
//TODO dragBoundsProperty is in view coordinates because ruler.positionProperty is in view coordinates.
// Drag bounds for the ruler, in model coordinates.
// This keeps a part of the ruler inside the visible bounds of the ScreenView.
const dragBoundsProperty = new DerivedProperty(
[ visibleBoundsProperty ],
( visibleBounds: Bounds2 ) => {
[ visibleBoundsProperty, zoomTransformProperty ],
( visibleBounds: Bounds2, zoomTransform: ModelViewTransform2 ) => {
let viewDragBounds;
if ( ruler.isVertical ) {

// if vertical the left and right bounds of the ruler stay within visible bounds
// minimum visible length of the ruler is always showing inside top and bottom visible bounds.
return visibleBounds.withOffsets( 0,
-MINIMUM_VISIBLE_LENGTH,
-this.width,
-MINIMUM_VISIBLE_LENGTH + this.height );
viewDragBounds = visibleBounds.withOffsets( 0, -MINIMUM_VISIBLE_LENGTH,
-this.width, -MINIMUM_VISIBLE_LENGTH + this.height );
}
else {
// if horizontal ruler, the bottom and top bounds of the ruler stay within visible bounds
// minimum visible length of the ruler is always showing inside left and right visible bounds.
return visibleBounds.withOffsets( this.width - MINIMUM_VISIBLE_LENGTH,
0,
-MINIMUM_VISIBLE_LENGTH,
-this.height );
viewDragBounds = visibleBounds.withOffsets( this.width - MINIMUM_VISIBLE_LENGTH, 0,
-MINIMUM_VISIBLE_LENGTH, -this.height );
}
return zoomTransform.viewToModelBounds( viewDragBounds );
} );
dragBoundsProperty.link( dragBounds => {
ruler.positionProperty.value = dragBounds.closestPointTo( ruler.positionProperty.value );
Expand All @@ -138,6 +137,7 @@ class GORulerNode extends Node {
useInputListenerCursor: true,
positionProperty: ruler.positionProperty,
dragBoundsProperty: dragBoundsProperty,
transform: zoomTransformProperty.value,
start: () => this.moveToFront(),
end: ( event: SceneryEvent ) => {

Expand All @@ -150,6 +150,11 @@ class GORulerNode extends Node {
tandem: options.tandem.createTandem( 'dragListener' )
} );
this.addInputListener( this.dragListener );

// When the transform changes, up the DragListener
zoomTransformProperty.link( zoomTransform => {
this.dragListener.setTransform( zoomTransform );
} );
}

public setToolboxBounds( toolboxBounds: Bounds2 ): void {
Expand Down
2 changes: 1 addition & 1 deletion js/common/view/GOScreenView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class GOScreenView extends ScreenView {
} );

// create toolbox at the top right corner of the screen
const rulersToolbox = new RulersToolbox( [ verticalRulerNode, horizontalRulerNode ], {
const rulersToolbox = new RulersToolbox( [ verticalRulerNode, horizontalRulerNode ], zoomTransformProperty, {
rightTop: erodedLayoutBounds.rightTop,
tandem: options.tandem.createTandem( 'rulersToolbox' )
} );
Expand Down
23 changes: 19 additions & 4 deletions js/common/view/RulerIconNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
*/

import DerivedProperty from '../../../../axon/js/DerivedProperty.js';
import Property from '../../../../axon/js/Property.js';
import ModelViewTransform2 from '../../../../phetcommon/js/view/ModelViewTransform2.js';
import RulerNode from '../../../../scenery-phet/js/RulerNode.js';
import { DragListener, SceneryEvent } from '../../../../scenery/js/imports.js';
import geometricOptics from '../../geometricOptics.js';
import GORulerNode from './GORulerNode.js';
import GOConstants from '../GOConstants.js';

// constants
const ICON_WIDTH = 400;
Expand All @@ -24,7 +27,7 @@ class RulerIconNode extends RulerNode {
/**
* @param rulerNode
*/
constructor( rulerNode: GORulerNode ) {
constructor( rulerNode: GORulerNode, zoomTransformProperty: Property<ModelViewTransform2> ) {

const options = {

Expand Down Expand Up @@ -57,7 +60,7 @@ class RulerIconNode extends RulerNode {
const units = '';

super( ICON_WIDTH, ICON_HEIGHT, majorTickWidth, majorTickLabels, units, options );

this.scale( ICON_SCALE );

// pointer areas
Expand All @@ -75,9 +78,21 @@ class RulerIconNode extends RulerNode {
// Make the ruler visible.
rulerNode.ruler.visibleProperty.value = true;

// Position the center of the rulerNode at the pointer.
// Set position of the ruler so that the pointer is initially at the center of rulerNode.
assert && assert( event.pointer.point ); // {Vector2|null}
rulerNode.center = rulerNode.globalToParentPoint( event.pointer.point! );
const zoomTransform = zoomTransformProperty.value;
const viewPosition = rulerNode.globalToParentPoint( event.pointer.point! );
let x;
let y;
if ( rulerNode.ruler.isVertical ) {
x = viewPosition.x - GOConstants.RULER_HEIGHT / 2;
y = viewPosition.y - zoomTransform.modelToViewDeltaY( rulerNode.ruler.length ) / 2;
}
else {
x = viewPosition.x - zoomTransform.modelToViewDeltaX( rulerNode.ruler.length ) / 2;
y = viewPosition.y - GOConstants.RULER_HEIGHT / 2;
}
rulerNode.ruler.positionProperty.value = zoomTransform.viewToModelXY( x, y );

// Forward events to the RulerNode.
rulerNode.startDrag( event );
Expand Down
7 changes: 5 additions & 2 deletions js/common/view/RulersToolbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
* @author Chris Malley (PixelZoom, Inc.)
*/

import Property from '../../../../axon/js/Property.js';
import merge from '../../../../phet-core/js/merge.js';
import ModelViewTransform2 from '../../../../phetcommon/js/view/ModelViewTransform2.js';
import { HBox } from '../../../../scenery/js/imports.js';
import Panel from '../../../../sun/js/Panel.js';
import Tandem from '../../../../tandem/js/Tandem.js';
Expand All @@ -24,13 +26,14 @@ class RulersToolbox extends Panel {

/**
* @param rulerNodes - in the order that they appear in the toolbox, left to right
* @param zoomTransformProperty
* @param options
*/
constructor( rulerNodes: GORulerNode[], options: Options ) {
constructor( rulerNodes: GORulerNode[], zoomTransformProperty: Property<ModelViewTransform2>, options: Options ) {

const toolboxContent = new HBox( {
spacing: 30,
children: rulerNodes.map( rulerNode => new RulerIconNode( rulerNode ) ),
children: rulerNodes.map( rulerNode => new RulerIconNode( rulerNode, zoomTransformProperty ) ),
excludeInvisibleChildrenFromBounds: false
} );

Expand Down

0 comments on commit 35d9e75

Please sign in to comment.