# HG changeset patch # User Lucas Thompson # Date 1496339755 -3600 # Node ID f45a916eb5b1cc00a49d3ccea2a59a2cf637dbf7 # Parent a02e6ec4a9d2bad7662b126f1ce5f7ca852ab062 Use the cross hair layer for notes, tracks and curve. This involved bodging in unit to ShapedFeatureData, which isn't particularly easy to do because this isn't an encapsulated type. Need to come back to improving this, as I am monkey-patching a unit property onto Arrays etc. diff -r a02e6ec4a9d2 -r f45a916eb5b1 src/app/analysis-item/analysis-item.component.html --- a/src/app/analysis-item/analysis-item.component.html Thu Jun 01 16:26:52 2017 +0100 +++ b/src/app/analysis-item/analysis-item.component.html Thu Jun 01 18:55:55 2017 +0100 @@ -40,7 +40,7 @@ [onSeek]="onSeek" [curve]="item.collected" > - + - - + + - + { + Data extends ShapedFeatureData & {unit?: string}> { shape: Shape; - collected: Data; + collected: Data & {unit?: string}; } export class Vector extends ShapedFeature<'vector', VectorFeature> {} @@ -143,32 +145,46 @@ export function toKnownShape(response: SimpleResponse): KnownShapedFeature { const deducedShape = deduceHigherLevelFeatureShape(response); - switch (deducedShape) { - case 'vector': - return response.features as Vector; - case 'matrix': - return response.features as Matrix; - case 'tracks': - return response.features as Tracks; - case 'notes': - return { - shape: deducedShape, - collected: mapFeaturesToNotes( + const shaped: KnownShapedFeature | null = (() => { + switch (deducedShape) { + case 'vector': + return response.features as Vector; + case 'matrix': + return response.features as Matrix; + case 'tracks': + return response.features as Tracks; + case 'notes': + // TODO refactor + const notes: Note[] & {unit?: string} = mapFeaturesToNotes( response.features.collected as FeatureList, response.outputDescriptor - ) - }; - case 'instants': - const featureData = response.features.collected as FeatureList; - return { - shape: deducedShape, - collected: featureData.map(feature => ({ - time: toSeconds(feature.timestamp), - label: feature.label - })) - }; + ); + notes.unit = 'MIDI'; + return { + shape: deducedShape, + collected: notes, + }; + case 'instants': + const featureData = response.features.collected as FeatureList; + return { + shape: deducedShape, + collected: featureData.map(feature => ({ + time: toSeconds(feature.timestamp), + label: feature.label + })) + }; + } + })(); + const unit = response.outputDescriptor.configured.unit; + if (shaped) { + const bodgeUnit = (shaped: KnownShapedFeature) => { + (shaped.collected as any).unit = unit; + return shaped; + }; + return unit && !shaped.collected.unit ? bodgeUnit(shaped) : shaped; + } else { + throwShapeError(); } - throwShapeError(); } export interface PlotData { diff -r a02e6ec4a9d2 -r f45a916eb5b1 src/app/visualisations/curve/curve.component.ts --- a/src/app/visualisations/curve/curve.component.ts Thu Jun 01 16:26:52 2017 +0100 +++ b/src/app/visualisations/curve/curve.component.ts Thu Jun 01 18:55:55 2017 +0100 @@ -7,7 +7,7 @@ Input } from '@angular/core'; import {OnSeekHandler} from '../../playhead/PlayHeadHelpers'; -import {VectorFeature} from 'piper/HigherLevelUtilities'; +import {TracksFeature, VectorFeature} from 'piper/HigherLevelUtilities'; @Component({ selector: 'ugly-curve', @@ -17,7 +17,7 @@ [width]="width" [onSeek]="onSeek" [colour]="colour" - [tracks]="[curve]" + [tracks]="tracks" > `, changeDetection: ChangeDetectionStrategy.OnPush @@ -26,6 +26,13 @@ @Input() timeline: Timeline; // TODO refactor WaveComponents to have own Timeline, sharing a TimeContext @Input() onSeek: OnSeekHandler; @Input() width: number; - @Input() curve: VectorFeature; + @Input() set curve(curve: VectorFeature & {unit?: string}) { + const tempTracks: TracksFeature & {unit?: string} = [curve]; + tempTracks.unit = curve.unit; + this.tracks = tempTracks; + } + + private tracks: TracksFeature & {unit?: string}; + @Input() colour: string; } diff -r a02e6ec4a9d2 -r f45a916eb5b1 src/app/visualisations/notes/notes.component.ts --- a/src/app/visualisations/notes/notes.component.ts Thu Jun 01 16:26:52 2017 +0100 +++ b/src/app/visualisations/notes/notes.component.ts Thu Jun 01 18:55:55 2017 +0100 @@ -2,9 +2,10 @@ * Created by lucast on 31/05/2017. */ import { + InspectableVerticallyBoundedComponent, VerticallyBounded, - VerticallyBoundedWavesComponent, - VerticalScaleRenderer + VerticalScaleRenderer, + VerticalValueInspectorRenderer } from '../waves-base.component'; import { ChangeDetectionStrategy, @@ -21,10 +22,11 @@ changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: VerticallyBounded, useExisting: NotesComponent }, - { provide: VerticalScaleRenderer, useExisting: NotesComponent } + { provide: VerticalScaleRenderer, useExisting: NotesComponent }, + {provide: VerticalValueInspectorRenderer, useExisting: NotesComponent } ] }) -export class NotesComponent extends VerticallyBoundedWavesComponent { +export class NotesComponent extends InspectableVerticallyBoundedComponent { private currentVerticalRange: [number, number]; get range(): [number, number] { diff -r a02e6ec4a9d2 -r f45a916eb5b1 src/app/visualisations/waves-base.component.ts --- a/src/app/visualisations/waves-base.component.ts Thu Jun 01 16:26:52 2017 +0100 +++ b/src/app/visualisations/waves-base.component.ts Thu Jun 01 18:55:55 2017 +0100 @@ -22,7 +22,7 @@ export abstract class VerticalValueInspectorRenderer extends VerticalScaleRenderer { // TODO how do I know these layers are actually 'describable'? - abstract renderInspector(range: [number, number]): void; + abstract renderInspector(range: [number, number], unit?: string): void; } export abstract class WavesComponent @@ -209,8 +209,10 @@ @Input() set onSeek(handler: OnSeekHandler) { this.wrappedSeekHandler = (x: number) => { handler(x); - this.highlight.currentPosition = x; - this.highlight.update(); + if (this.highlight) { + this.highlight.currentPosition = x; + this.highlight.update(); + } }; } @@ -219,18 +221,20 @@ } - renderInspector(range: [number, number]): void { - this.highlight = new Waves.helpers.HighlightLayer( - this.cachedFeatureLayers, - { - opacity: 0.7, - height: this.height, - color: '#c33c54', // TODO pass in? - labelOffset: 38, - yDomain: range, - unit: ''// TODO - } - ); - this.addLayer(this.highlight); + renderInspector(range: [number, number], unit?: string): void { + if (range) { + this.highlight = new Waves.helpers.HighlightLayer( + this.cachedFeatureLayers, + { + opacity: 0.7, + height: this.height, + color: '#c33c54', // TODO pass in? + labelOffset: 38, + yDomain: range, + unit: unit || this.feature.unit || '' + } + ); + this.addLayer(this.highlight); + } } }