Skip to content

Commit

Permalink
Adding a proper thumb node, see #54
Browse files Browse the repository at this point in the history
  • Loading branch information
AgustinVallejo committed Jan 10, 2025
1 parent dc630d0 commit f61cc74
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 39 deletions.
73 changes: 43 additions & 30 deletions js/bloch-sphere/view/MeasurementTimerControl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@
import NumberProperty from '../../../../axon/js/NumberProperty.js';
import Dimension2 from '../../../../dot/js/Dimension2.js';
import Utils from '../../../../dot/js/Utils.js';
import Vector2 from '../../../../dot/js/Vector2.js';
import { Shape } from '../../../../kite/js/imports.js';
import optionize, { EmptySelfOptions } from '../../../../phet-core/js/optionize.js';
import Orientation from '../../../../phet-core/js/Orientation.js';
import WithRequired from '../../../../phet-core/js/types/WithRequired.js';
import ArrowNode from '../../../../scenery-phet/js/ArrowNode.js';
import PhetFont from '../../../../scenery-phet/js/PhetFont.js';
import { Color, Node, Path, Text } from '../../../../scenery/js/imports.js';
import { Color, Node, Path, PressListener, Text } from '../../../../scenery/js/imports.js';
import { PanelOptions } from '../../../../sun/js/Panel.js';
import Slider from '../../../../sun/js/Slider.js';
import Tandem from '../../../../tandem/js/Tandem.js';
import MeasurementSymbolNode from '../../common/view/MeasurementSymbolNode.js';
import quantumMeasurement from '../../quantumMeasurement.js';

Expand All @@ -36,19 +38,50 @@ export default class MeasurementTimerControl extends Node {
measurementTimeProperty: NumberProperty,
providedOptions: MeasurementTimerControlOptions ) {

// TODO: This should probably be rewritten to use thumbNode. Seems like that would be way simpler. See https://github.com/phetsims/quantum-measurement/issues/54.
const thumbOffset = 30;
const thumbDimensions = new Dimension2( 30, 30 );
const thumbPathOptions = {
fill: '#aaa',
fillHighlighted: '#fff',
stroke: 'black',
lineWidth: 2
};
const thumbNodeRect = new Path( new Shape().roundRect(
-thumbDimensions.width / 2,
thumbOffset - thumbDimensions.height / 2,
thumbDimensions.width,
thumbDimensions.height,
5,
5
), thumbPathOptions );
const thumbNode = new Node( {
children: [
new Path( new Shape().circle( 0, 0, 2 ).moveTo( 0, 0 ).lineTo( 0, thumbOffset - thumbDimensions.height / 2 ), thumbPathOptions ),
thumbNodeRect,
new MeasurementSymbolNode( {
center: new Vector2( 0, thumbOffset ),
scale: 0.8,
stroke: 'black'
} )
]
} );

// highlight thumb on pointer over
const pressListener = new PressListener( {
attach: false,
tandem: Tandem.OPT_OUT // Highlighting doesn't need instrumentation
} );
pressListener.isHighlightedProperty.link( isHighlighted => {
thumbNodeRect.fill = isHighlighted ? thumbPathOptions.fillHighlighted : thumbPathOptions.fill;
} );
thumbNode.addInputListener( pressListener );

const maxMeasurementTime = timeToMeasurementProperty.rangeProperty.value.max;
const minMeasurementTime = timeToMeasurementProperty.rangeProperty.value.getLength() / ( NUMBER_OF_MINOR_TICKS + 1 );
const thumbOffset = 30;
const thumbDimensions = new Dimension2( 30, 30 );
const timeToMeasurementSlider = new Slider( timeToMeasurementProperty, timeToMeasurementProperty.range, {
tandem: providedOptions.tandem.createTandem( 'timeToMeasurementSlider' ),
thumbSize: thumbDimensions,
thumbYOffset: thumbOffset,
thumbFill: 'white',
thumbFillHighlighted: '#ddd',
thumbCenterLineStroke: null,
thumbNode: thumbNode,
thumbYOffset: thumbOffset - 8,
trackSize: SLIDER_TRACK_SIZE,
trackFillEnabled: Color.BLACK,
constrainValue: value => {
Expand Down Expand Up @@ -84,30 +117,10 @@ export default class MeasurementTimerControl extends Node {
timeIndicator.centerX = measurementTime / timeToMeasurementProperty.rangeProperty.value.max * SLIDER_TRACK_SIZE.width;
} );

const thumbLine = new Path( new Shape().circle( 0, 0, 2 ).moveTo( 0, 0 ).lineTo( 0, thumbOffset - thumbDimensions.height / 2 ), {
fill: '#bbb',
stroke: 'black',
lineWidth: 2
} );

// TODO: Can the measurement symbol be a common code item? See https://github.com/phetsims/quantum-measurement/issues/54.

const measurementSymbol = new MeasurementSymbolNode();

timeToMeasurementProperty.link( time => {
thumbLine.centerX = time / maxMeasurementTime * SLIDER_TRACK_SIZE.width;
thumbLine.top = -2;

measurementSymbol.centerX = time / maxMeasurementTime * SLIDER_TRACK_SIZE.width;
measurementSymbol.centerY = thumbOffset / 2 + thumbDimensions.height / 2;
} );

const options = optionize<MeasurementTimerControlOptions, SelfOptions, PanelOptions>()( {
children: [
timeIndicator,
timeToMeasurementSlider,
thumbLine,
measurementSymbol
timeToMeasurementSlider
]
}, providedOptions );

Expand Down
28 changes: 19 additions & 9 deletions js/common/view/MeasurementSymbolNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,44 @@

import Vector2 from '../../../../dot/js/Vector2.js';
import { Shape } from '../../../../kite/js/imports.js';
import { combineOptions } from '../../../../phet-core/js/optionize.js';
import optionize from '../../../../phet-core/js/optionize.js';
import ArrowNode from '../../../../scenery-phet/js/ArrowNode.js';
import { Node, NodeOptions, Path } from '../../../../scenery/js/imports.js';
import { Node, NodeOptions, Path, TPaint } from '../../../../scenery/js/imports.js';
import quantumMeasurement from '../../quantumMeasurement.js';

type SelfOptions = {
stroke?: TPaint;
};

type MeasurementSymbolNodeOptions = SelfOptions & NodeOptions;

export default class MeasurementSymbolNode extends Node {
public constructor( providedOptions?: NodeOptions ) {
public constructor( providedOptions?: MeasurementSymbolNodeOptions ) {
const options = optionize<MeasurementSymbolNodeOptions, SelfOptions, NodeOptions>()( {
stroke: 'white'
}, providedOptions );

const measurementArcPath = new Path( Shape.arc( 0, 0, 20, 0, Math.PI, true ), {
stroke: 'white',
stroke: options.stroke,
lineWidth: 5,
lineCap: 'round',
lineJoin: 'round',
center: new Vector2( 0, 5 ),
scale: 0.6
} );
const measurementArrowPath = new ArrowNode( 0, 0, 30, -35, {
fill: 'white',
stroke: 'white',
fill: options.stroke,
stroke: options.stroke,
lineWidth: 1,
lineCap: 'round',
lineJoin: 'round',
center: new Vector2( 5, 4 ),
scale: 0.6
} );

super( combineOptions<NodeOptions>( {
children: [ measurementArcPath, measurementArrowPath ]
}, providedOptions ) );
options.children = [ measurementArcPath, measurementArrowPath ];

super( options );
}
}

Expand Down

0 comments on commit f61cc74

Please sign in to comment.