1 <!DOCTYPE html> 2 <!-- 3 Copyright (c) 2013 The Chromium Authors. All rights reserved. 4 Use of this source code is governed by a BSD-style license that can be 5 found in the LICENSE file. 6 --> 7 <link rel="stylesheet" href="/ui/tracks/track.css"> 8 9 <link rel="import" href="/ui/base/container_that_decorates_its_children.html"> 10 <link rel="import" href="/ui/base/ui.html"> 11 12 <script> 13 'use strict'; 14 15 /** 16 * @fileoverview Renders an array of slices into the provided div, 17 * using a child canvas element. Uses a FastRectRenderer to draw only 18 * the visible slices. 19 */ 20 tr.exportTo('tr.ui.tracks', function() { 21 /** 22 * The base class for all tracks. 23 * @constructor 24 */ 25 var Track = tr.ui.b.define('track', 26 tr.ui.b.ContainerThatDecoratesItsChildren); 27 Track.prototype = { 28 __proto__: tr.ui.b.ContainerThatDecoratesItsChildren.prototype, 29 30 decorate: function(viewport) { 31 tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this); 32 if (viewport === undefined) 33 throw new Error('viewport is required when creating a Track.'); 34 35 this.viewport_ = viewport; 36 this.classList.add('track'); 37 }, 38 39 get viewport() { 40 return this.viewport_; 41 }, 42 43 get drawingContainer() { 44 var cur = this; 45 while (cur) { 46 if (cur instanceof tr.ui.tracks.DrawingContainer) 47 return cur; 48 cur = cur.parentElement; 49 } 50 return undefined; 51 }, 52 53 get eventContainer() { 54 }, 55 56 invalidateDrawingContainer: function() { 57 var dc = this.drawingContainer; 58 if (dc) 59 dc.invalidate(); 60 }, 61 62 context: function() { 63 // This is a little weird here, but we have to be able to walk up the 64 // parent tree to get the context. 65 if (!this.parentNode) 66 return undefined; 67 if (!this.parentNode.context) 68 throw new Error('Parent container does not support context() method.'); 69 return this.parentNode.context(); 70 }, 71 72 decorateChild_: function(childTrack) { 73 }, 74 75 undecorateChild_: function(childTrack) { 76 if (childTrack.detach) 77 childTrack.detach(); 78 }, 79 80 updateContents_: function() { 81 }, 82 83 drawTrack: function(type) { 84 var ctx = this.context(); 85 86 var pixelRatio = window.devicePixelRatio || 1; 87 var bounds = this.getBoundingClientRect(); 88 var canvasBounds = ctx.canvas.getBoundingClientRect(); 89 90 ctx.save(); 91 ctx.translate(0, pixelRatio * (bounds.top - canvasBounds.top)); 92 93 var dt = this.viewport.currentDisplayTransform; 94 var viewLWorld = dt.xViewToWorld(0); 95 var viewRWorld = dt.xViewToWorld(bounds.width * pixelRatio); 96 97 this.draw(type, viewLWorld, viewRWorld); 98 ctx.restore(); 99 }, 100 101 draw: function(type, viewLWorld, viewRWorld) { 102 }, 103 104 addEventsToTrackMap: function(eventToTrackMap) { 105 }, 106 107 addContainersToTrackMap: function(containerToTrackMap) { 108 }, 109 110 addIntersectingEventsInRangeToSelection: function( 111 loVX, hiVX, loVY, hiVY, selection) { 112 113 var pixelRatio = window.devicePixelRatio || 1; 114 var dt = this.viewport.currentDisplayTransform; 115 var viewPixWidthWorld = dt.xViewVectorToWorld(1); 116 var loWX = dt.xViewToWorld(loVX * pixelRatio); 117 var hiWX = dt.xViewToWorld(hiVX * pixelRatio); 118 119 var clientRect = this.getBoundingClientRect(); 120 var a = Math.max(loVY, clientRect.top); 121 var b = Math.min(hiVY, clientRect.bottom); 122 if (a > b) 123 return; 124 125 this.addIntersectingEventsInRangeToSelectionInWorldSpace( 126 loWX, hiWX, viewPixWidthWorld, selection); 127 }, 128 129 addIntersectingEventsInRangeToSelectionInWorldSpace: function( 130 loWX, hiWX, viewPixWidthWorld, selection) { 131 }, 132 133 /** 134 * Gets implemented by supporting track types. The method adds the event 135 * closest to worldX to the selection. 136 * 137 * @param {number} worldX The position that is looked for. 138 * @param {number} worldMaxDist The maximum distance allowed from worldX to 139 * the event. 140 * @param {number} loY Lower Y bound of the search interval in view space. 141 * @param {number} hiY Upper Y bound of the search interval in view space. 142 * @param {Selection} selection Selection to which to add hits. 143 */ 144 addClosestEventToSelection: function( 145 worldX, worldMaxDist, loY, hiY, selection) { 146 }, 147 148 addClosestInstantEventToSelection: function(instantEvents, worldX, 149 worldMaxDist, selection) { 150 var instantEvent = tr.b.findClosestElementInSortedArray( 151 instantEvents, 152 function(x) { return x.start; }, 153 worldX, 154 worldMaxDist); 155 156 if (!instantEvent) 157 return; 158 159 selection.push(instantEvent); 160 } 161 }; 162 163 return { 164 Track: Track 165 }; 166 }); 167 </script> 168