# HG changeset patch # User Lucas Thompson # Date 1499276532 -3600 # Node ID 64ed45a0bad344023b0055d58c7f4f199dc2c54b # Parent f2bb5ddae86704bc6cfc8fc850bf4fb10fbad952 Introduce PlayheadRenderer, implement in the waves base. Make VerticallyBounded and VerticalScaleRenderer generic and remove bin equivalents. Forward calls for a PlayheadRenderer from VerticalScaleComponent on to its children. Also update other components accordingly. diff -r f2bb5ddae867 -r 64ed45a0bad3 src/app/analysis-item/analysis-item.component.html --- a/src/app/analysis-item/analysis-item.component.html Wed Jul 05 17:28:24 2017 +0100 +++ b/src/app/analysis-item/analysis-item.component.html Wed Jul 05 18:42:12 2017 +0100 @@ -78,7 +78,7 @@ [duration]="getDuration()" > - - + >; + @ContentChildren(PlayheadRenderer) wavesChildren: QueryList; @Input() colour: string; @Input() set isActive(isActive: boolean) { this.mIsActive = isActive; @@ -63,17 +63,13 @@ private setupAnimatedPlayheads(): void { if (this.wavesChildren && this.mIsActive) { this.wavesChildren.forEach(component => { - const cursor = new Waves.helpers.CursorLayer({ - height: component.height, - color: this.colour, - }); - cursor.currentPosition = this.player.getCurrentTime(); + const cursor = component.renderPlayhead( + this.player.getCurrentTime(), + this.colour + ); this.removers.push( - component.addLayer(cursor), - this.renderLoop.addPlayingTask(currentTime => { - cursor.currentPosition = currentTime; - cursor.update(); - }) + cursor.remove, + this.renderLoop.addPlayingTask(cursor.update) ); }); } diff -r f2bb5ddae867 -r 64ed45a0bad3 src/app/visualisations/cross-hair-inspector.component.ts --- a/src/app/visualisations/cross-hair-inspector.component.ts Wed Jul 05 17:28:24 2017 +0100 +++ b/src/app/visualisations/cross-hair-inspector.component.ts Wed Jul 05 18:42:12 2017 +0100 @@ -11,6 +11,7 @@ QueryList } from '@angular/core'; import { + PlayheadRenderer, VerticalValueInspectorRenderer } from './waves-base.component'; import {VerticalScaleComponent} from './vertical-scale.component'; @@ -23,7 +24,10 @@ @Component({ selector: 'ugly-cross-hair-inspector', template: '', - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [ + {provide: PlayheadRenderer, useExisting: CrossHairInspectorComponent } + ] }) export class CrossHairInspectorComponent extends VerticalScaleComponent implements AfterViewInit, OnDestroy { diff -r f2bb5ddae867 -r 64ed45a0bad3 src/app/visualisations/curve/curve.component.ts --- a/src/app/visualisations/curve/curve.component.ts Wed Jul 05 17:28:24 2017 +0100 +++ b/src/app/visualisations/curve/curve.component.ts Wed Jul 05 18:42:12 2017 +0100 @@ -10,6 +10,8 @@ import {OnSeekHandler} from '../../playhead/PlayHeadHelpers'; import {VectorFeature} from 'piper/HigherLevelUtilities'; import { + PlayheadManager, + PlayheadRenderer, VerticallyBounded, VerticalScaleRenderer, VerticalValueInspectorRenderer, @@ -33,10 +35,13 @@ {provide: VerticallyBounded, useExisting: CurveComponent }, {provide: VerticalScaleRenderer, useExisting: CurveComponent}, {provide: VerticalValueInspectorRenderer, useExisting: CurveComponent}, + {provide: PlayheadRenderer, useExisting: CurveComponent }, {provide: WavesComponent, useExisting: CurveComponent} ] }) -export class CurveComponent implements VerticalValueInspectorRenderer { +export class CurveComponent + implements VerticalValueInspectorRenderer, PlayheadRenderer { + @Input() timeline: Timeline; // TODO refactor WaveComponents to have own Timeline, sharing a TimeContext @Input() onSeek: OnSeekHandler; @Input() width: number; @@ -45,6 +50,10 @@ @Input() duration: number; @ViewChild(TracksComponent) tracksComponent: TracksComponent; + renderPlayhead(initialTime: number, colour: string): PlayheadManager { + return this.tracksComponent.renderPlayhead(initialTime, colour); + } + renderInspector(range: [number, number], unit?: string): void { this.tracksComponent.renderInspector(range, unit); } diff -r f2bb5ddae867 -r 64ed45a0bad3 src/app/visualisations/grid/grid.component.ts --- a/src/app/visualisations/grid/grid.component.ts Wed Jul 05 17:28:24 2017 +0100 +++ b/src/app/visualisations/grid/grid.component.ts Wed Jul 05 18:42:12 2017 +0100 @@ -2,10 +2,8 @@ * Created by lucast on 31/05/2017. */ import { - VerticallyBinned, VerticallyBinnedWavesComponent, - VerticalBinNameRenderer, - WavesComponent + WavesComponent, PlayheadRenderer, VerticallyBounded, VerticalScaleRenderer } from '../waves-base.component'; import { ChangeDetectionStrategy, @@ -23,8 +21,9 @@ styleUrls: ['../waves-template.css'], changeDetection: ChangeDetectionStrategy.OnPush, providers: [ - {provide: VerticallyBinned, useExisting: GridComponent }, - {provide: VerticalBinNameRenderer, useExisting: GridComponent }, + {provide: VerticallyBounded, useExisting: GridComponent }, + {provide: VerticalScaleRenderer, useExisting: GridComponent}, + {provide: PlayheadRenderer, useExisting: GridComponent }, {provide: WavesComponent, useExisting: GridComponent} ] }) @@ -65,7 +64,7 @@ ]; } - get binNames(): string[] { + get range(): string[] { if (!this.feature.binNames || this.feature.binNames.length === 0) { const binCount = (this.feature.data.length > 0 ? this.feature.data[0].length : 0); diff -r f2bb5ddae867 -r 64ed45a0bad3 src/app/visualisations/instants/instants.component.ts --- a/src/app/visualisations/instants/instants.component.ts Wed Jul 05 17:28:24 2017 +0100 +++ b/src/app/visualisations/instants/instants.component.ts Wed Jul 05 18:42:12 2017 +0100 @@ -1,7 +1,7 @@ /** * Created by lucast on 31/05/2017. */ -import {WavesComponent} from '../waves-base.component'; +import {PlayheadRenderer, WavesComponent} from '../waves-base.component'; import { ChangeDetectionStrategy, Component, @@ -16,6 +16,7 @@ styleUrls: ['../waves-template.css'], changeDetection: ChangeDetectionStrategy.OnPush, providers: [ + {provide: PlayheadRenderer, useExisting: InstantsComponent}, {provide: WavesComponent, useExisting: InstantsComponent} ] }) diff -r f2bb5ddae867 -r 64ed45a0bad3 src/app/visualisations/notes/notes.component.ts --- a/src/app/visualisations/notes/notes.component.ts Wed Jul 05 17:28:24 2017 +0100 +++ b/src/app/visualisations/notes/notes.component.ts Wed Jul 05 18:42:12 2017 +0100 @@ -3,6 +3,7 @@ */ import { InspectableVerticallyBoundedComponent, + PlayheadRenderer, VerticallyBounded, VerticalScaleRenderer, VerticalValueInspectorRenderer, @@ -25,6 +26,7 @@ { provide: VerticallyBounded, useExisting: NotesComponent }, { provide: VerticalScaleRenderer, useExisting: NotesComponent }, {provide: VerticalValueInspectorRenderer, useExisting: NotesComponent }, + {provide: PlayheadRenderer, useExisting: NotesComponent}, {provide: WavesComponent, useExisting: NotesComponent} ] }) diff -r f2bb5ddae867 -r 64ed45a0bad3 src/app/visualisations/tracks/tracks.components.ts --- a/src/app/visualisations/tracks/tracks.components.ts Wed Jul 05 17:28:24 2017 +0100 +++ b/src/app/visualisations/tracks/tracks.components.ts Wed Jul 05 18:42:12 2017 +0100 @@ -3,9 +3,11 @@ */ import { InspectableVerticallyBoundedComponent, + PlayheadRenderer, VerticallyBounded, VerticalScaleRenderer, - VerticalValueInspectorRenderer, WavesComponent, + VerticalValueInspectorRenderer, + WavesComponent } from '../waves-base.component'; import { ChangeDetectionStrategy, @@ -25,6 +27,7 @@ {provide: VerticallyBounded, useExisting: TracksComponent }, {provide: VerticalScaleRenderer, useExisting: TracksComponent}, {provide: VerticalValueInspectorRenderer, useExisting: TracksComponent}, + {provide: PlayheadRenderer, useExisting: TracksComponent }, {provide: WavesComponent, useExisting: TracksComponent} ], }) diff -r f2bb5ddae867 -r 64ed45a0bad3 src/app/visualisations/vertical-binned.component.ts --- a/src/app/visualisations/vertical-binned.component.ts Wed Jul 05 17:28:24 2017 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/** - * Created by lucas on 01/06/2017. - */ -import {VerticalBinNameRenderer} from './waves-base.component'; -import { - ChangeDetectionStrategy, - Component, - ContentChildren, - QueryList, - AfterViewInit -} from '@angular/core'; - -@Component({ - selector: 'ugly-vertical-binned', - template: '', - changeDetection: ChangeDetectionStrategy.OnPush -}) -export class VerticalBinnedComponent implements AfterViewInit { - - @ContentChildren( - VerticalBinNameRenderer - ) bounded: QueryList; - protected cachedBinNames: string[]; - - ngAfterViewInit(): void { - this.bounded.forEach(component => { - this.cachedBinNames = component.binNames; - if (this.cachedBinNames) { - component.renderNames(this.cachedBinNames); - } - }); - } -} diff -r f2bb5ddae867 -r 64ed45a0bad3 src/app/visualisations/vertical-scale.component.ts --- a/src/app/visualisations/vertical-scale.component.ts Wed Jul 05 17:28:24 2017 +0100 +++ b/src/app/visualisations/vertical-scale.component.ts Wed Jul 05 18:42:12 2017 +0100 @@ -1,7 +1,11 @@ /** * Created by lucas on 01/06/2017. */ -import {VerticalScaleRenderer} from './waves-base.component'; +import { + PlayheadManager, + PlayheadRenderer, + VerticalScaleRenderer +} from './waves-base.component'; import { ChangeDetectionStrategy, Component, @@ -13,14 +17,20 @@ @Component({ selector: 'ugly-vertical-scale', template: '', - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [ + {provide: PlayheadRenderer, useExisting: VerticalScaleComponent } + ] }) -export class VerticalScaleComponent implements AfterViewInit { +export class VerticalScaleComponent implements AfterViewInit, PlayheadRenderer { @ContentChildren( VerticalScaleRenderer - ) bounded: QueryList; - protected cachedRange: [number, number]; + ) bounded: QueryList>; + @ContentChildren( + PlayheadRenderer + ) seekable: QueryList; + protected cachedRange: any; ngAfterViewInit(): void { this.bounded.forEach(component => { @@ -30,4 +40,16 @@ } }); } + + renderPlayhead(initialTime: number, colour: string): PlayheadManager { + const rendered = this.seekable + .filter(x => x !== this) // why does QueryList consider itself as a child? + .map(component => component.renderPlayhead(initialTime, colour)); + return { + update: (time: number) => { + rendered.forEach(component => component.update(time)); + }, + remove: () => rendered.map(component => component.remove) + }; + } } diff -r f2bb5ddae867 -r 64ed45a0bad3 src/app/visualisations/waveform/waveform.component.ts --- a/src/app/visualisations/waveform/waveform.component.ts Wed Jul 05 17:28:24 2017 +0100 +++ b/src/app/visualisations/waveform/waveform.component.ts Wed Jul 05 18:42:12 2017 +0100 @@ -4,7 +4,7 @@ ChangeDetectionStrategy } from '@angular/core'; import wavesUI from 'waves-ui-piper'; -import {WavesComponent} from '../waves-base.component'; +import {PlayheadRenderer, WavesComponent} from '../waves-base.component'; @Component({ @@ -13,6 +13,7 @@ styleUrls: ['../waves-template.css'], changeDetection: ChangeDetectionStrategy.OnPush, providers: [ + {provide: PlayheadRenderer, useExisting: WaveformComponent }, {provide: WavesComponent, useExisting: WaveformComponent} ] }) diff -r f2bb5ddae867 -r 64ed45a0bad3 src/app/visualisations/waves-base.component.ts --- a/src/app/visualisations/waves-base.component.ts Wed Jul 05 17:28:24 2017 +0100 +++ b/src/app/visualisations/waves-base.component.ts Wed Jul 05 18:42:12 2017 +0100 @@ -11,33 +11,35 @@ const trackIdGenerator = countingIdProvider(0); // has to be an abstract class vs as interface for Angular's DI -export abstract class VerticallyBounded { - abstract get range(): [number, number]; +export abstract class VerticallyBounded { + abstract get range(): T; } -export abstract class VerticalScaleRenderer extends VerticallyBounded { - abstract renderScale(range: [number, number]): void; -} - -export abstract class VerticallyBinned { - abstract get binNames(): string[]; -} - -export abstract class VerticalBinNameRenderer extends VerticallyBinned { - abstract renderNames(binNames: string[]): void; +export abstract class VerticalScaleRenderer extends VerticallyBounded { + abstract renderScale(range: T): void; } export abstract class VerticalValueInspectorRenderer - extends VerticalScaleRenderer { + extends VerticalScaleRenderer<[number, number]> { // TODO how do I know these layers are actually 'describable'? abstract renderInspector(range: [number, number], unit?: string): void; abstract get updatePosition(): OnSeekHandler; } +export abstract class PlayheadManager { + abstract update(time: number): void; + abstract remove(): void; +} + +export abstract class PlayheadRenderer { + abstract renderPlayhead(initialTime: number, colour: string): PlayheadManager; +} + export type LayerRemover = () => void; export abstract class WavesComponent - implements AfterViewInit { + implements AfterViewInit, PlayheadRenderer { + @ViewChild('track') trackContainer: ElementRef; @Input() set width(width: number) { if (this.timeline) { @@ -83,6 +85,22 @@ this.update(); } + renderPlayhead(initialTime: number, colour: string): PlayheadManager { + console.warn('waves base render playhead'); + const cursor = new Waves.helpers.CursorLayer({ + height: this.height, + color: colour, + }); + cursor.currentPosition = initialTime; + return { + update: currentTime => { + cursor.currentPosition = currentTime; + cursor.update(); + }, + remove: this.addLayer(cursor) + }; + } + private update(): void { if (!this.waveTrack || !this.mFeature) { return; @@ -207,7 +225,7 @@ export abstract class VerticallyBoundedWavesComponent extends WavesComponent - implements VerticalScaleRenderer { + implements VerticalScaleRenderer<[number, number]> { abstract range: [number, number]; renderScale(range: [number, number]): void { @@ -222,10 +240,10 @@ export abstract class VerticallyBinnedWavesComponent extends WavesComponent - implements VerticalBinNameRenderer { - abstract binNames: string[]; + implements VerticalScaleRenderer { + abstract range: string[]; - renderNames(binNames: string[]): void { + renderScale(binNames: string[]): void { this.addLayer(new Waves.helpers.DiscreteScaleLayer({ tickColor: this.colour, textColor: this.colour,