Skip to content

Commit

Permalink
Refactoring Preparation Area, see #54
Browse files Browse the repository at this point in the history
  • Loading branch information
AgustinVallejo committed Dec 26, 2024
1 parent 605eed8 commit 6827eab
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 89 deletions.
112 changes: 112 additions & 0 deletions js/bloch-sphere/view/BlochSpherePreparationArea.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright 2024, University of Colorado Boulder

/**
* Zone where the Bloch Sphere direction is set by the user,
* it includdes sliders for the polar and azimuthal angles and a ComboBox to select the direction.
*
* @author Agustín Vallejo
*/

import BlochSphereModel from 'model/BlochSphereModel.js';
import Dimension2 from '../../../../dot/js/Dimension2.js';
import Vector2 from '../../../../dot/js/Vector2.js';
import optionize, { EmptySelfOptions } from '../../../../phet-core/js/optionize.js';
import WithRequired from '../../../../phet-core/js/types/WithRequired.js';
import PhetFont from '../../../../scenery-phet/js/PhetFont.js';
import { Node, Text, VBox, VBoxOptions } from '../../../../scenery/js/imports.js';
import ComboBox, { ComboBoxItem } from '../../../../sun/js/ComboBox.js';
import Panel from '../../../../sun/js/Panel.js';
import Slider from '../../../../sun/js/Slider.js';
import QuantumMeasurementColors from '../../common/QuantumMeasurementColors.js';
import BlochSphereNode from '../../common/view/BlochSphereNode.js';
import quantumMeasurement from '../../quantumMeasurement.js';
import { StateDirection } from '../model/StateDirection.js';
import BlochSphereNumericalEquationNode from './BlochSphereNumericalEquationNode.js';
import BlochSphereSymbolicEquationNode from './BlochSphereSymbolicEquationNode.js';

type SelfOptions = EmptySelfOptions;

export type BlochSpherePreparationAreaOptions = SelfOptions & WithRequired<VBoxOptions, 'tandem'>;

export default class BlochSpherePreparationArea extends VBox {

public constructor( model: BlochSphereModel, parentNode: Node, providedOptions: BlochSpherePreparationAreaOptions ) {

const polarSlider = new Slider( model.blochSphere.polarAngleProperty, model.blochSphere.polarAngleProperty.range, {
center: new Vector2( 100, 200 ),
tandem: providedOptions.tandem.createTandem( 'polarSlider' ),
thumbFill: '#444',
trackSize: new Dimension2( 150, 0.5 ),
majorTickLength: 10
} );
const azimuthSlider = new Slider( model.blochSphere.azimuthalAngleProperty, model.blochSphere.azimuthalAngleProperty.range, {
center: new Vector2( 100, 100 ),
tandem: providedOptions.tandem.createTandem( 'azimuthSlider' ),
thumbFill: '#444',
trackSize: new Dimension2( 150, 0.5 ),
majorTickLength: 10
} );

polarSlider.addMajorTick( 0, new Text( '0', { font: new PhetFont( 15 ) } ) );
polarSlider.addMajorTick( Math.PI, new Text( 'π', { font: new PhetFont( 15 ) } ) );

azimuthSlider.addMajorTick( 0, new Text( '0', { font: new PhetFont( 15 ) } ) );
azimuthSlider.addMajorTick( 2 * Math.PI, new Text( '2π', { font: new PhetFont( 15 ) } ) );

const comboBoxItems: ComboBoxItem<StateDirection>[] = StateDirection.enumeration.values.map( direction => {
return {
value: direction,
createNode: () => new Text( direction.description, { font: new PhetFont( 16 ) } )
};
} );

const directionComboBox = new ComboBox( model.selectedStateDirectionProperty, comboBoxItems, parentNode, {
tandem: providedOptions.tandem.createTandem( 'directionComboBox' )
} );

const slidersPanel = new Panel( new VBox( {
spacing: 10,
children: [
directionComboBox,
new Text( 'Polar Angle (θ): ', { font: new PhetFont( 15 ) } ), // Theta symbol: θ
polarSlider,
new Text( 'Azimuthal Angle (φ)', { font: new PhetFont( 15 ) } ), // Phi symbol: φ
azimuthSlider
]
} ), {
fill: QuantumMeasurementColors.controlPanelFillColorProperty,
stroke: QuantumMeasurementColors.controlPanelStrokeColorProperty,
minWidth: 270
} );

const blochSphereNode = new BlochSphereNode(
model.blochSphere, {
tandem: providedOptions.tandem.createTandem( 'blochSphereNode' ),
expandBounds: false,
drawTitle: false
} );

const options = optionize<BlochSpherePreparationAreaOptions, SelfOptions, VBoxOptions>()( {
spacing: 10,
align: 'center',
children: [
new Text( 'State to Prepare', { font: new PhetFont( { size: 20, weight: 'bolder' } ) } ),
new BlochSphereSymbolicEquationNode(),
new Panel(
new BlochSphereNumericalEquationNode( model ), {
fill: '#aff',
cornerRadius: 5,
stroke: null,
xMargin: 10
}
),
blochSphereNode,
slidersPanel
]
}, providedOptions );

super( options );
}
}

quantumMeasurement.register( 'BlochSpherePreparationArea', BlochSpherePreparationArea );
95 changes: 6 additions & 89 deletions js/bloch-sphere/view/BlochSphereScreenView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,17 @@
/**
* Main screen view class for the "Bloch Sphere" screen.
*
* @author John Blanco, PhET Interactive Simulations
* @author Agustín Vallejo
*/

import BlochSphereModel from 'model/BlochSphereModel.js';
import Dimension2 from '../../../../dot/js/Dimension2.js';
import Vector2 from '../../../../dot/js/Vector2.js';
import ScreenView from '../../../../joist/js/ScreenView.js';
import PhetFont from '../../../../scenery-phet/js/PhetFont.js';
import { Color, Image, Line, Text, VBox } from '../../../../scenery/js/imports.js';
import ComboBox, { ComboBoxItem } from '../../../../sun/js/ComboBox.js';
import Panel from '../../../../sun/js/Panel.js';
import Slider from '../../../../sun/js/Slider.js';
import { Color, Image, Line } from '../../../../scenery/js/imports.js';
import Tandem from '../../../../tandem/js/Tandem.js';
import blochSphereScreenMockup_png from '../../../images/blochSphereScreenMockup_png.js';
import QuantumMeasurementColors from '../../common/QuantumMeasurementColors.js';
import BlochSphereNode from '../../common/view/BlochSphereNode.js';
import QuantumMeasurementScreenView from '../../common/view/QuantumMeasurementScreenView.js';
import quantumMeasurement from '../../quantumMeasurement.js';
import { StateDirection } from '../model/StateDirection.js';
import BlochSphereNumericalEquationNode from './BlochSphereNumericalEquationNode.js';
import BlochSphereSymbolicEquationNode from './BlochSphereSymbolicEquationNode.js';
import BlochSpherePreparationArea from './BlochSpherePreparationArea.js';

export default class BlochSphereScreenView extends QuantumMeasurementScreenView {

Expand All @@ -37,78 +27,9 @@ export default class BlochSphereScreenView extends QuantumMeasurementScreenView
tandem: tandem
} );

const polarSlider = new Slider( model.blochSphere.polarAngleProperty, model.blochSphere.polarAngleProperty.range, {
center: new Vector2( 100, 200 ),
tandem: tandem.createTandem( 'polarSlider' ),
thumbFill: '#444',
trackSize: new Dimension2( 150, 0.5 ),
majorTickLength: 10
} );
const azimuthSlider = new Slider( model.blochSphere.azimuthalAngleProperty, model.blochSphere.azimuthalAngleProperty.range, {
center: new Vector2( 100, 100 ),
tandem: tandem.createTandem( 'azimuthSlider' ),
thumbFill: '#444',
trackSize: new Dimension2( 150, 0.5 ),
majorTickLength: 10
} );

polarSlider.addMajorTick( 0, new Text( '0', { font: new PhetFont( 15 ) } ) );
polarSlider.addMajorTick( Math.PI, new Text( 'π', { font: new PhetFont( 15 ) } ) );

azimuthSlider.addMajorTick( 0, new Text( '0', { font: new PhetFont( 15 ) } ) );
azimuthSlider.addMajorTick( 2 * Math.PI, new Text( '2π', { font: new PhetFont( 15 ) } ) );

const comboBoxItems: ComboBoxItem<StateDirection>[] = StateDirection.enumeration.values.map( direction => {
return {
value: direction,
createNode: () => new Text( direction.description, { font: new PhetFont( 16 ) } )
};
} );

const directionComboBox = new ComboBox( model.selectedStateDirectionProperty, comboBoxItems, this, {
tandem: tandem.createTandem( 'directionComboBox' )
} );

const slidersPanel = new Panel( new VBox( {
spacing: 10,
children: [
directionComboBox,
new Text( 'Polar Angle (θ): ', { font: new PhetFont( 15 ) } ), // Theta symbol: θ
polarSlider,
new Text( 'Azimuthal Angle (φ)', { font: new PhetFont( 15 ) } ), // Phi symbol: φ
azimuthSlider
]
} ), {
fill: QuantumMeasurementColors.controlPanelFillColorProperty,
stroke: QuantumMeasurementColors.controlPanelStrokeColorProperty,
minWidth: 270
} );

const blochSphereNode = new BlochSphereNode(
model.blochSphere, {
tandem: tandem.createTandem( 'blochSphereNode' ),
expandBounds: false,
drawTitle: false
} );

const blochSpherePreparationArea = new VBox( {
const preparationArea = new BlochSpherePreparationArea( model, this, {
left: this.layoutBounds.left + 20,
spacing: 10,
align: 'center',
children: [
new Text( 'State to Prepare', { font: new PhetFont( { size: 20, weight: 'bolder' } ) } ),
new BlochSphereSymbolicEquationNode(),
new Panel(
new BlochSphereNumericalEquationNode( model ), {
fill: '#aff',
cornerRadius: 5,
stroke: null,
xMargin: 10
}
),
blochSphereNode,
slidersPanel
]
tandem: tandem.createTandem( 'preparationArea' )
} );

// Add the vertical line that will sit between the preparation and measurement areas.
Expand All @@ -120,11 +41,7 @@ export default class BlochSphereScreenView extends QuantumMeasurementScreenView
} );
this.addChild( dividingLine );

this.addChild( blochSpherePreparationArea );

this.mockupOpacityProperty && this.mockupOpacityProperty.link( opacity => {
blochSpherePreparationArea.opacity = 1 - opacity;
} );
this.addChild( preparationArea );
}

public override reset(): void {
Expand Down

0 comments on commit 6827eab

Please sign in to comment.