blob: fe33453b34306b4f4cb7365e250dbd16950e52a4 [file] [log] [blame]
Chris Craikb122baf2015-03-05 13:58:42 -08001<!DOCTYPE html>
2<!--
3Copyright (c) 2014 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7
8<link rel="import" href="/base/range.html">
9
10<script>
11'use strict';
12
13tv.exportTo('tv.c', function() {
14 /**
15 * @constructor
16 */
17 function SnapIndicator(y, height) {
18 this.y = y;
19 this.height = height;
20 }
21
22 /**
23 * The interesting part of the world.
24 *
25 * @constructor
26 */
27 function TimelineInterestRange(vp) {
28 this.viewport_ = vp;
29
30 this.range_ = new tv.b.Range();
31
32 this.leftSelected_ = false;
33 this.rightSelected_ = false;
34
35 this.leftSnapIndicator_ = undefined;
36 this.rightSnapIndicator_ = undefined;
37 }
38
39 TimelineInterestRange.prototype = {
40 get isEmpty() {
41 return this.range_.isEmpty;
42 },
43
44 reset: function() {
45 this.range_.reset();
46 this.leftSelected_ = false;
47 this.rightSelected_ = false;
48 this.leftSnapIndicator_ = undefined;
49 this.rightSnapIndicator_ = undefined;
50 this.viewport_.dispatchChangeEvent();
51 },
52
53 get min() {
54 return this.range_.min;
55 },
56
57 set min(min) {
58 this.range_.min = min;
59 this.viewport_.dispatchChangeEvent();
60 },
61
62 get max() {
63 return this.range_.max;
64 },
65
66 set max(max) {
67 this.range_.max = max;
68 this.viewport_.dispatchChangeEvent();
69 },
70
71 set: function(range) {
72 this.range_.reset();
73 this.range_.addRange(range);
74 this.viewport_.dispatchChangeEvent();
75 },
76
77 setMinAndMax: function(min, max) {
78 this.range_.min = min;
79 this.range_.max = max;
80 this.viewport_.dispatchChangeEvent();
81 },
82
83 get range() {
84 return this.range_.range;
85 },
86
87 asRangeObject: function() {
88 var range = new tv.b.Range();
89 range.addRange(this.range_);
90 return range;
91 },
92
93 get leftSelected() {
94 return this.leftSelected_;
95 },
96
97 set leftSelected(leftSelected) {
98 if (this.leftSelected_ == leftSelected)
99 return;
100 this.leftSelected_ = leftSelected;
101 this.viewport_.dispatchChangeEvent();
102 },
103
104 get rightSelected() {
105 return this.rightSelected_;
106 },
107
108 set rightSelected(rightSelected) {
109 if (this.rightSelected_ == rightSelected)
110 return;
111 this.rightSelected_ = rightSelected;
112 this.viewport_.dispatchChangeEvent();
113 },
114
115 get leftSnapIndicator() {
116 return this.leftSnapIndicator_;
117 },
118
119 set leftSnapIndicator(leftSnapIndicator) {
120 this.leftSnapIndicator_ = leftSnapIndicator;
121 this.viewport_.dispatchChangeEvent();
122 },
123
124 get rightSnapIndicator() {
125 return this.rightSnapIndicator_;
126 },
127
128 set rightSnapIndicator(rightSnapIndicator) {
129 this.rightSnapIndicator_ = rightSnapIndicator;
130 this.viewport_.dispatchChangeEvent();
131 },
132
133 draw: function(ctx, viewLWorld, viewRWorld) {
134 if (this.range_.isEmpty)
135 return;
136 var dt = this.viewport_.currentDisplayTransform;
137
138 var markerLWorld = this.min;
139 var markerRWorld = this.max;
140
141 var markerLView = Math.round(dt.xWorldToView(markerLWorld));
142 var markerRView = Math.round(dt.xWorldToView(markerRWorld));
143
144 ctx.fillStyle = 'rgba(0, 0, 0, 0.2)';
145 if (markerLWorld > viewLWorld) {
146 ctx.fillRect(dt.xWorldToView(viewLWorld), 0,
147 markerLView, ctx.canvas.height);
148 }
149
150 if (markerRWorld < viewRWorld) {
151 ctx.fillRect(markerRView, 0,
152 dt.xWorldToView(viewRWorld), ctx.canvas.height);
153 }
154
155 var pixelRatio = window.devicePixelRatio || 1;
156 ctx.lineWidth = Math.round(pixelRatio);
157 if (this.range_.range > 0) {
158 this.drawLine_(ctx, viewLWorld, viewRWorld,
159 ctx.canvas.height, this.min, this.leftSelected_);
160 this.drawLine_(ctx, viewLWorld, viewRWorld,
161 ctx.canvas.height, this.max, this.rightSelected_);
162 } else {
163 this.drawLine_(ctx, viewLWorld, viewRWorld,
164 ctx.canvas.height, this.min,
165 this.leftSelected_ || this.rightSelected_);
166 }
167 ctx.lineWidth = 1;
168 },
169
170 drawLine_: function(ctx, viewLWorld, viewRWorld, height, ts, selected) {
171 if (ts < viewLWorld || ts >= viewRWorld)
172 return;
173
174 var dt = this.viewport_.currentDisplayTransform;
175 var viewX = Math.round(dt.xWorldToView(ts));
176
177 // Apply subpixel translate to get crisp lines.
178 // http://www.mobtowers.com/html5-canvas-crisp-lines-every-time/
179 ctx.save();
180 ctx.translate((Math.round(ctx.lineWidth) % 2) / 2, 0);
181
182 ctx.beginPath();
183 tv.c.drawLine(ctx, viewX, 0, viewX, height);
184 if (selected)
185 ctx.strokeStyle = 'rgb(255, 0, 0)';
186 else
187 ctx.strokeStyle = 'rgb(0, 0, 0)';
188 ctx.stroke();
189
190 ctx.restore();
191 },
192
193 drawIndicators: function(ctx, viewLWorld, viewRWorld) {
194 if (this.leftSnapIndicator_) {
195 this.drawIndicator_(ctx, viewLWorld, viewRWorld,
196 this.range_.min,
197 this.leftSnapIndicator_,
198 this.leftSelected_);
199 }
200 if (this.rightSnapIndicator_) {
201 this.drawIndicator_(ctx, viewLWorld, viewRWorld,
202 this.range_.max,
203 this.rightSnapIndicator_,
204 this.rightSelected_);
205 }
206 },
207
208 drawIndicator_: function(ctx, viewLWorld, viewRWorld,
209 xWorld, si, selected) {
210 var dt = this.viewport_.currentDisplayTransform;
211
212 var viewX = Math.round(dt.xWorldToView(xWorld));
213
214 // Apply subpixel translate to get crisp lines.
215 // http://www.mobtowers.com/html5-canvas-crisp-lines-every-time/
216 ctx.save();
217 ctx.translate((Math.round(ctx.lineWidth) % 2) / 2, 0);
218
219 var pixelRatio = window.devicePixelRatio || 1;
220 var viewY = si.y * devicePixelRatio;
221 var viewHeight = si.height * devicePixelRatio;
222 var arrowSize = 4 * pixelRatio;
223
224 if (selected)
225 ctx.fillStyle = 'rgb(255, 0, 0)';
226 else
227 ctx.fillStyle = 'rgb(0, 0, 0)';
228 tv.c.drawTriangle(ctx,
229 viewX - arrowSize * 0.75, viewY,
230 viewX + arrowSize * 0.75, viewY,
231 viewX, viewY + arrowSize);
232 ctx.fill();
233 tv.c.drawTriangle(ctx,
234 viewX - arrowSize * 0.75, viewY + viewHeight,
235 viewX + arrowSize * 0.75, viewY + viewHeight,
236 viewX, viewY + viewHeight - arrowSize);
237 ctx.fill();
238
239 ctx.restore();
240 }
241 };
242
243 return {
244 SnapIndicator: SnapIndicator,
245 TimelineInterestRange: TimelineInterestRange
246 };
247});
248</script>