changeset 488:64ed45a0bad3

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.
author Lucas Thompson <dev@lucas.im>
date Wed, 05 Jul 2017 18:42:12 +0100
parents f2bb5ddae867
children ab43880f1cd5
files src/app/analysis-item/analysis-item.component.html src/app/app.module.ts src/app/playhead/waves-ui-play-head.component.ts src/app/visualisations/cross-hair-inspector.component.ts src/app/visualisations/curve/curve.component.ts src/app/visualisations/grid/grid.component.ts src/app/visualisations/instants/instants.component.ts src/app/visualisations/notes/notes.component.ts src/app/visualisations/tracks/tracks.components.ts src/app/visualisations/vertical-binned.component.ts src/app/visualisations/vertical-scale.component.ts src/app/visualisations/waveform/waveform.component.ts src/app/visualisations/waves-base.component.ts
diffstat 13 files changed, 103 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- 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()"
             ></ugly-notes>
           </ugly-cross-hair-inspector>
-          <ugly-vertical-binned
+          <ugly-vertical-scale
             *ngSwitchCase="'matrix'"
           >
             <ugly-grid
@@ -89,7 +89,7 @@
               [grid]="item.collected"
               [duration]="getDuration()"
             ></ugly-grid>
-          </ugly-vertical-binned>
+          </ugly-vertical-scale>
           <ugly-instants
             *ngSwitchCase="'instants'"
             [colour]="getNextColour()"
--- a/src/app/app.module.ts	Wed Jul 05 17:28:24 2017 +0100
+++ b/src/app/app.module.ts	Wed Jul 05 18:42:12 2017 +0100
@@ -35,7 +35,6 @@
 import {InstantsComponent} from './visualisations/instants/instants.component';
 import {GridComponent} from './visualisations/grid/grid.component';
 import {VerticalScaleComponent} from './visualisations/vertical-scale.component';
-import {VerticalBinnedComponent} from './visualisations/vertical-binned.component';
 import {CrossHairInspectorComponent} from './visualisations/cross-hair-inspector.component';
 import {RenderLoopService} from './services/render-loop/render-loop.service';
 import {WavesPlayHeadComponent} from './playhead/waves-ui-play-head.component';
@@ -142,7 +141,6 @@
     InstantsComponent,
     GridComponent,
     VerticalScaleComponent,
-    VerticalBinnedComponent,
     CrossHairInspectorComponent,
     WavesPlayHeadComponent,
     ActionTrayComponent
--- a/src/app/playhead/waves-ui-play-head.component.ts	Wed Jul 05 17:28:24 2017 +0100
+++ b/src/app/playhead/waves-ui-play-head.component.ts	Wed Jul 05 18:42:12 2017 +0100
@@ -10,7 +10,7 @@
   QueryList
 } from '@angular/core';
 import {
-  LayerRemover,
+  LayerRemover, PlayheadRenderer,
   WavesComponent
 } from '../visualisations/waves-base.component';
 import Waves from 'waves-ui-piper';
@@ -27,7 +27,7 @@
 })
 export class WavesPlayHeadComponent implements AfterViewInit, OnDestroy {
 
-  @ContentChildren(WavesComponent) wavesChildren: QueryList<WavesComponent<any>>;
+  @ContentChildren(PlayheadRenderer) wavesChildren: QueryList<PlayheadRenderer>;
   @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)
         );
       });
     }
--- 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: '<ng-content></ng-content>',
-  changeDetection: ChangeDetectionStrategy.OnPush
+  changeDetection: ChangeDetectionStrategy.OnPush,
+  providers: [
+    {provide: PlayheadRenderer, useExisting: CrossHairInspectorComponent }
+  ]
 })
 export class CrossHairInspectorComponent extends VerticalScaleComponent
   implements AfterViewInit, OnDestroy {
--- 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);
   }
--- 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);
--- 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}
   ]
 })
--- 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}
   ]
 })
--- 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}
   ],
 })
--- 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: '<ng-content></ng-content>',
-  changeDetection: ChangeDetectionStrategy.OnPush
-})
-export class VerticalBinnedComponent implements AfterViewInit {
-
-  @ContentChildren(
-    VerticalBinNameRenderer
-  ) bounded: QueryList<VerticalBinNameRenderer>;
-  protected cachedBinNames: string[];
-
-  ngAfterViewInit(): void {
-    this.bounded.forEach(component => {
-      this.cachedBinNames = component.binNames;
-      if (this.cachedBinNames) {
-        component.renderNames(this.cachedBinNames);
-      }
-    });
-  }
-}
--- 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: '<ng-content></ng-content>',
-  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<VerticalScaleRenderer>;
-  protected cachedRange: [number, number];
+  ) bounded: QueryList<VerticalScaleRenderer<any>>;
+  @ContentChildren(
+    PlayheadRenderer
+  ) seekable: QueryList<PlayheadRenderer>;
+  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)
+    };
+  }
 }
--- 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}
   ]
 })
--- 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<T> {
+  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<T> extends VerticallyBounded<T> {
+  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<T extends ShapedFeatureData | AudioBuffer>
-  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
 <T extends ShapedFeatureData> extends WavesComponent<T>
-  implements VerticalScaleRenderer {
+  implements VerticalScaleRenderer<[number, number]> {
   abstract range: [number, number];
 
   renderScale(range: [number, number]): void {
@@ -222,10 +240,10 @@
 
 export abstract class VerticallyBinnedWavesComponent
 <T extends ShapedFeatureData> extends WavesComponent<T>
-  implements VerticalBinNameRenderer {
-  abstract binNames: string[];
+  implements VerticalScaleRenderer<string[]> {
+  abstract range: string[];
 
-  renderNames(binNames: string[]): void {
+  renderScale(binNames: string[]): void {
     this.addLayer(new Waves.helpers.DiscreteScaleLayer({
       tickColor: this.colour,
       textColor: this.colour,