dev@380: /** dev@380: * Created by lucast on 31/05/2017. dev@380: */ dev@390: import { dev@394: InspectableVerticallyBoundedComponent, dev@488: PlayheadRenderer, dev@489: VerticallyLabelled, dev@394: VerticalScaleRenderer, dev@405: VerticalValueInspectorRenderer, dev@405: WavesComponent dev@390: } from '../waves-base.component'; dev@380: import { dev@380: ChangeDetectionStrategy, dev@380: Component, dev@380: Input, dev@380: } from '@angular/core'; dev@380: import {Note} from '../FeatureUtilities'; dev@380: import Waves from 'waves-ui-piper'; dev@380: dev@380: @Component({ dev@380: selector: 'ugly-notes', dev@380: templateUrl: '../waves-template.html', dev@380: styleUrls: ['../waves-template.css'], dev@390: changeDetection: ChangeDetectionStrategy.OnPush, dev@392: providers: [ dev@489: { provide: VerticallyLabelled, useExisting: NotesComponent }, dev@394: { provide: VerticalScaleRenderer, useExisting: NotesComponent }, dev@405: {provide: VerticalValueInspectorRenderer, useExisting: NotesComponent }, dev@488: {provide: PlayheadRenderer, useExisting: NotesComponent}, dev@405: {provide: WavesComponent, useExisting: NotesComponent} dev@392: ] dev@380: }) dev@394: export class NotesComponent extends InspectableVerticallyBoundedComponent { dev@390: private currentVerticalRange: [number, number]; dev@390: dev@489: get labels(): [number, number] { dev@390: return this.currentVerticalRange; dev@390: } dev@380: dev@380: @Input() set notes(notes: Note[]) { dev@383: this.feature = notes; dev@380: } dev@380: dev@383: protected get featureLayers(): Layer[] { dev@390: this.currentVerticalRange = findVerticalRange(this.feature); dev@383: return [ dev@380: new Waves.helpers.PianoRollLayer( dev@383: this.feature, dev@380: { dev@380: height: this.height, dev@380: color: this.colour, dev@390: yDomain: this.currentVerticalRange dev@380: } dev@383: ) dev@383: ]; dev@380: } dev@380: } dev@380: dev@380: // TODO there might be scope to create a generic utility function like this dev@380: function findVerticalRange(notes: Note[]): [number, number] { dev@380: let [min, max] = notes.reduce((acc, note) => { dev@380: const [min, max] = acc; dev@380: return [Math.min (min, note.pitch), Math.max (max, note.pitch)]; dev@380: }, [Infinity, -Infinity]); dev@380: if (min === Infinity || min < 0 || max < 0) { dev@380: min = 0; dev@380: max = 127; dev@380: } dev@380: // round min and max to octave boundaries (starting at C as in MIDI) dev@380: return [ dev@380: 12 * Math.floor(min / 12), dev@380: 12 * Math.ceil(max / 12) dev@380: ]; dev@380: }