<commit_before>// Copyright 2018, University of Colorado Boulder

/**
 * A point tool displays the (x,y) coordinates of a point on the graph.
 * If it's sufficiently close to a curve, it will snap to that curve.
 *
 * @author <NAME>
 * @author <NAME> (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const Circle = require( 'SCENERY/nodes/Circle' );
  const CoordinatesNode = require( 'GRAPHING_QUADRATICS/common/view/CoordinatesNode' );
  const DerivedProperty = require( 'AXON/DerivedProperty' );
  const DerivedPropertyIO = require( 'AXON/DerivedPropertyIO' );
  const DragListener = require( 'SCENERY/listeners/DragListener' );
  const GQConstants = require( 'GRAPHING_QUADRATICS/common/GQConstants' );
  const GQQueryParameters = require( 'GRAPHING_QUADRATICS/common/GQQueryParameters' );
  const graphingQuadratics = require( 'GRAPHING_QUADRATICS/graphingQuadratics' );
  const Image = require( 'SCENERY/nodes/Image' );
  const Node = require( 'SCENERY/nodes/Node' );
  const NullableIO = require( 'TANDEM/types/NullableIO' );
  const Path = require( 'SCENERY/nodes/Path' );
  const PhetFont = require( 'SCENERY_PHET/PhetFont' );
  const Property = require( 'AXON/Property' );
  const Rectangle = require( 'SCENERY/nodes/Rectangle' );
  const Shape = require( 'KITE/Shape' );
  const Tandem = require( 'TANDEM/Tandem' );
  const Vector2 = require( 'DOT/Vector2' );
  const Vector2IO = require( 'DOT/Vector2IO' );

  // images
  const pointToolLeftImage = require( 'image!GRAPHING_QUADRATICS/point_tool_left.png' );
  const pointToolRightImage = require( 'image!GRAPHING_QUADRATICS/point_tool_right.png' );

  // constants
  const VALUE_WINDOW_CENTER_X = 44; // center of the value window, relative to the left edge of pointToolLeftImage

  class PointToolNode extends Node {

    /**
     * @param {PointTool} pointTool
     * @param {ModelViewTransform2} modelViewTransform
     * @param {Graph} graph
     * @param {BooleanProperty} graphContentsVisibleProperty
     * @param {Object} [options]
     */
    constructor( pointTool, modelViewTransform, graph, graphContentsVisibleProperty, options ) {

      options = _.extend( {
        cursor: 'pointer',
        backgroundNormalColor: 'white',
        foregroundNormalColor: 'black',
        foregroundHighlightColor: 'white',

        // phet-io
        tandem: Tandem.required,
        phetioComponentOptions: { visibleProperty: { phetioFeatured: true } }

      }, options );

      // use the image file that corresponds to the probeSide
      const bodyImage = ( pointTool.probeSide === 'left' ) ? pointToolLeftImage : pointToolRightImage;
      const bodyNode = new Image( bodyImage, { centerY: 0 } );

      const probeNode = new ProbeNode();

      const coordinatesProperty = new DerivedProperty( [ pointTool.locationProperty ],
        location => ( graph.contains( location ) ? location : null ), {
          isValidValue: value => ( value instanceof Vector2 || value === null ),
          tandem: options.tandem.createTandem( 'coordinatesProperty' ),
          phetioDocumentation: 'coordinates displayed by this point tool, null if off the graph',
          phetioType: DerivedPropertyIO( NullableIO( Vector2IO ) )
        } );

      // coordinates display
      const coordinatesNode = new CoordinatesNode( coordinatesProperty, {
        font: new PhetFont( { size: 15, weight: 'bold' } ),
        foregroundColor: 'white',
        backgroundOpacity: 0, // don't use the CoordinatesNode background, because it resizes to the value
        xMargin: 0,
        yMargin: 0,
        decimals: GQConstants.POINT_TOOL_DECIMALS,
        maxWidth: 60, // constrain width, determined empirically, dependent on bodyNode
        tandem: options.tandem.createTandem( 'coordinatesNode' ),
        phetioDocumentation: 'coordinates displayed by this point tool'
      } );

      // background behind the coordinates, sized to the body so that it shows through the window
      const backgroundNode = new Rectangle( 0, 0, bodyNode.width - 10, bodyNode.height - 10 );

      // Put probe on correct side of body. Move the body, since the probe establishes the origin.
      if ( pointTool.probeSide === 'left' ) {
        bodyNode.left = probeNode.right - 1; // -1 for overlap, so you don't see a gap
      }
      else {
        probeNode.setScaleMagnitude( -1, 1 ); // reflect about the y axis
        bodyNode.right = probeNode.left + 1; // +1 for overlap, so you don't see a gap
      }
      backgroundNode.center = bodyNode.center;
<commit_msg>feature PointToolNode.coordinatesProperty (derived, read-only), #112<commit_after>// Copyright 2018, University of Colorado Boulder

/**
 * A point tool displays the (x,y) coordinates of a point on the graph.
 * If it's sufficiently close to a curve, it will snap to that curve.
 *
 * @author <NAME>
 * @author <NAME> (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const Circle = require( 'SCENERY/nodes/Circle' );
  const CoordinatesNode = require( 'GRAPHING_QUADRATICS/common/view/CoordinatesNode' );
  const DerivedProperty = require( 'AXON/DerivedProperty' );
  const DerivedPropertyIO = require( 'AXON/DerivedPropertyIO' );
  const DragListener = require( 'SCENERY/listeners/DragListener' );
  const GQConstants = require( 'GRAPHING_QUADRATICS/common/GQConstants' );
  const GQQueryParameters = require( 'GRAPHING_QUADRATICS/common/GQQueryParameters' );
  const graphingQuadratics = require( 'GRAPHING_QUADRATICS/graphingQuadratics' );
  const Image = require( 'SCENERY/nodes/Image' );
  const Node = require( 'SCENERY/nodes/Node' );
  const NullableIO = require( 'TANDEM/types/NullableIO' );
  const Path = require( 'SCENERY/nodes/Path' );
  const PhetFont = require( 'SCENERY_PHET/PhetFont' );
  const Property = require( 'AXON/Property' );
  const Rectangle = require( 'SCENERY/nodes/Rectangle' );
  const Shape = require( 'KITE/Shape' );
  const Tandem = require( 'TANDEM/Tandem' );
  const Vector2 = require( 'DOT/Vector2' );
  const Vector2IO = require( 'DOT/Vector2IO' );

  // images
  const pointToolLeftImage = require( 'image!GRAPHING_QUADRATICS/point_tool_left.png' );
  const pointToolRightImage = require( 'image!GRAPHING_QUADRATICS/point_tool_right.png' );

  // constants
  const VALUE_WINDOW_CENTER_X = 44; // center of the value window, relative to the left edge of pointToolLeftImage

  class PointToolNode extends Node {

    /**
     * @param {PointTool} pointTool
     * @param {ModelViewTransform2} modelViewTransform
     * @param {Graph} graph
     * @param {BooleanProperty} graphContentsVisibleProperty
     * @param {Object} [options]
     */
    constructor( pointTool, modelViewTransform, graph, graphContentsVisibleProperty, options ) {

      options = _.extend( {
        cursor: 'pointer',
        backgroundNormalColor: 'white',
        foregroundNormalColor: 'black',
        foregroundHighlightColor: 'white',

        // phet-io
        tandem: Tandem.required,
        phetioComponentOptions: { visibleProperty: { phetioFeatured: true } }

      }, options );

      // use the image file that corresponds to the probeSide
      const bodyImage = ( pointTool.probeSide === 'left' ) ? pointToolLeftImage : pointToolRightImage;
      const bodyNode = new Image( bodyImage, { centerY: 0 } );

      const probeNode = new ProbeNode();

      const coordinatesProperty = new DerivedProperty( [ pointTool.locationProperty ],
        location => ( graph.contains( location ) ? location : null ), {
          isValidValue: value => ( value instanceof Vector2 || value === null ),
          tandem: options.tandem.createTandem( 'coordinatesProperty' ),
          phetioDocumentation: 'coordinates displayed by this point tool, null if off the graph',
          phetioType: DerivedPropertyIO( NullableIO( Vector2IO ) ),
          phetioFeatured: true
        } );

      // coordinates display
      const coordinatesNode = new CoordinatesNode( coordinatesProperty, {
        font: new PhetFont( { size: 15, weight: 'bold' } ),
        foregroundColor: 'white',
        backgroundOpacity: 0, // don't use the CoordinatesNode background, because it resizes to the value
        xMargin: 0,
        yMargin: 0,
        decimals: GQConstants.POINT_TOOL_DECIMALS,
        maxWidth: 60, // constrain width, determined empirically, dependent on bodyNode
        tandem: options.tandem.createTandem( 'coordinatesNode' ),
        phetioDocumentation: 'coordinates displayed by this point tool'
      } );

      // background behind the coordinates, sized to the body so that it shows through the window
      const backgroundNode = new Rectangle( 0, 0, bodyNode.width - 10, bodyNode.height - 10 );

      // Put probe on correct side of body. Move the body, since the probe establishes the origin.
      if ( pointTool.probeSide === 'left' ) {
        bodyNode.left = probeNode.right - 1; // -1 for overlap, so you don't see a gap
      }
      else {
        probeNode.setScaleMagnitude( -1, 1 ); // reflect about the y axis
        bodyNode.right = probeNode.left + 1; // +1 for overlap, so you don't see a gap
      }
      backgroundNode.center = bodyNode.center;

{'fraction_non_alphanumeric': 0.10514248280379954, 'fraction_numerical': 0.0075335735342286275, 'mean_word_length': 3.3187175860443188, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '644537', 'n_tokens_mistral': 2777, 'n_tokens_neox': 2645, 'n_words': 772}