blob: 9b87b087fa8cba1063975eafce4c9c186fc7583c [file] [log] [blame]
Chris Craikb122baf2015-03-05 13:58:42 -08001<!DOCTYPE html>
2<!--
3Copyright (c) 2013 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="stylesheet" href="/core/tracks/rect_track.css">
9
Chris Craik19832152015-04-16 15:43:38 -070010<link rel="import" href="/core/trace_model/proxy_selectable_item.html">
Chris Craikb122baf2015-03-05 13:58:42 -080011<link rel="import" href="/core/tracks/heading_track.html">
12<link rel="import" href="/core/fast_rect_renderer.html">
13<link rel="import" href="/core/draw_helpers.html">
14<link rel="import" href="/base/sorted_array_utils.html">
15<link rel="import" href="/base/ui.html">
16
17<script>
18'use strict';
19
20tv.exportTo('tv.c.tracks', function() {
21
22 /**
23 * A track that displays an array of Rect objects.
24 * @constructor
25 * @extends {HeadingTrack}
26 */
27 var RectTrack = tv.b.ui.define(
28 'rect-track', tv.c.tracks.HeadingTrack);
29
30 RectTrack.prototype = {
31
32 __proto__: tv.c.tracks.HeadingTrack.prototype,
33
34 decorate: function(viewport) {
35 tv.c.tracks.HeadingTrack.prototype.decorate.call(this, viewport);
36 this.classList.add('rect-track');
37 this.asyncStyle_ = false;
38 this.rects_ = null;
39 },
40
41 get asyncStyle() {
42 return this.asyncStyle_;
43 },
44
45 set asyncStyle(v) {
46 this.asyncStyle_ = !!v;
47 },
48
49 get rects() {
50 return this.rects_;
51 },
52
53 set rects(rects) {
54 this.rects_ = rects || [];
55 this.invalidateDrawingContainer();
56 },
57
58 get height() {
59 return window.getComputedStyle(this).height;
60 },
61
62 set height(height) {
63 this.style.height = height;
64 this.invalidateDrawingContainer();
65 },
66
67 get hasVisibleContent() {
68 return this.rects_.length > 0;
69 },
70
Chris Craikb122baf2015-03-05 13:58:42 -080071 draw: function(type, viewLWorld, viewRWorld) {
72 switch (type) {
Chris Craik19832152015-04-16 15:43:38 -070073 case tv.c.tracks.DrawType.GENERAL_EVENT:
Chris Craikb122baf2015-03-05 13:58:42 -080074 this.drawRects_(viewLWorld, viewRWorld);
75 break;
76 }
77 },
78
79 drawRects_: function(viewLWorld, viewRWorld) {
80 var ctx = this.context();
81
82 ctx.save();
83 var bounds = this.getBoundingClientRect();
84 tv.c.drawSlices(
85 ctx,
86 this.viewport.currentDisplayTransform,
87 viewLWorld,
88 viewRWorld,
89 bounds.height,
90 this.rects_,
91 this.asyncStyle_);
92 ctx.restore();
93
94 if (bounds.height <= 6)
95 return;
96
97 var fontSize, yOffset;
98 if (bounds.height < 15) {
99 fontSize = 6;
100 yOffset = 1.0;
101 } else {
102 fontSize = 10;
103 yOffset = 2.5;
104 }
105 tv.c.drawLabels(
106 ctx,
107 this.viewport.currentDisplayTransform,
108 viewLWorld,
109 viewRWorld,
110 this.rects_,
111 this.asyncStyle_,
112 fontSize,
113 yOffset);
114 },
115
116 addEventsToTrackMap: function(eventToTrackMap) {
117 if (this.rects_ === undefined || this.rects_ === null)
118 return;
119
120 this.rects_.forEach(function(rect) {
Chris Craik19832152015-04-16 15:43:38 -0700121 rect.addToTrackMap(eventToTrackMap, this);
Chris Craikb122baf2015-03-05 13:58:42 -0800122 }, this);
123 },
124
Chris Craik44c28202015-05-12 17:25:16 -0700125 addIntersectingEventsInRangeToSelectionInWorldSpace: function(
Chris Craikb122baf2015-03-05 13:58:42 -0800126 loWX, hiWX, viewPixWidthWorld, selection) {
127 function onRect(rect) {
Chris Craik19832152015-04-16 15:43:38 -0700128 rect.addToSelection(selection);
Chris Craikb122baf2015-03-05 13:58:42 -0800129 }
130 onRect = onRect.bind(this);
131 tv.b.iterateOverIntersectingIntervals(this.rects_,
132 function(x) { return x.start; },
133 function(x) { return x.duration; },
134 loWX, hiWX,
135 onRect);
136 },
137
138 /**
Chris Craikb122baf2015-03-05 13:58:42 -0800139 * Add the item to the left or right of the provided event, if any, to the
140 * selection.
141 * @param {rect} The current rect.
142 * @param {Number} offset Number of rects away from the event to look.
143 * @param {Selection} selection The selection to add an event to,
144 * if found.
145 * @return {boolean} Whether an event was found.
146 * @private
147 */
Chris Craik44c28202015-05-12 17:25:16 -0700148 addEventNearToProvidedEventToSelection: function(event, offset, selection) {
Chris Craik19832152015-04-16 15:43:38 -0700149 var index = tv.b.findFirstIndexInArray(this.rects_, function(rect) {
150 return rect.modelItem === event;
151 });
152 if (index === -1)
Chris Craikb122baf2015-03-05 13:58:42 -0800153 return false;
154
155 var newIndex = index + offset;
156 if (newIndex < 0 || newIndex >= this.rects_.length)
157 return false;
158
Chris Craik19832152015-04-16 15:43:38 -0700159 this.rects_[newIndex].addToSelection(selection);
Chris Craikb122baf2015-03-05 13:58:42 -0800160 return true;
161 },
162
Chris Craik44c28202015-05-12 17:25:16 -0700163 addAllEventsMatchingFilterToSelection: function(filter, selection) {
Chris Craikb122baf2015-03-05 13:58:42 -0800164 for (var i = 0; i < this.rects_.length; ++i) {
Chris Craik19832152015-04-16 15:43:38 -0700165 // TODO(petrcermak): Rather than unpacking the proxy item here,
166 // we should probably add an addToSelectionIfMatching(selection, filter)
167 // method to SelectableItem (#900).
168 var modelItem = this.rects_[i].modelItem;
169 if (!modelItem)
170 continue;
171 if (filter.matchSlice(modelItem))
172 selection.push(modelItem);
Chris Craikb122baf2015-03-05 13:58:42 -0800173 }
174 },
175
176 addClosestEventToSelection: function(worldX, worldMaxDist, loY, hiY,
177 selection) {
178 var rect = tv.b.findClosestIntervalInSortedIntervals(
179 this.rects_,
180 function(x) { return x.start; },
181 function(x) { return x.end; },
182 worldX,
183 worldMaxDist);
184
Chris Craik19832152015-04-16 15:43:38 -0700185 if (!rect)
186 return;
187
188 rect.addToSelection(selection);
Chris Craikb122baf2015-03-05 13:58:42 -0800189 }
190 };
191
Chris Craik19832152015-04-16 15:43:38 -0700192 /**
193 * A filled rectangle with a title.
194 *
195 * @constructor
196 * @extends {ProxySelectableItem}
197 */
198 function Rect(modelItem, title, colorId, start, duration) {
199 tv.c.trace_model.ProxySelectableItem.call(this, modelItem);
200 this.title = title;
201 this.colorId = colorId;
202 this.start = start;
203 this.duration = duration;
204 this.end = start + duration;
205 };
206
207 Rect.prototype = {
208 __proto__: tv.c.trace_model.ProxySelectableItem.prototype
209 };
210
Chris Craikb122baf2015-03-05 13:58:42 -0800211 return {
Chris Craik19832152015-04-16 15:43:38 -0700212 RectTrack: RectTrack,
213 Rect: Rect
Chris Craikb122baf2015-03-05 13:58:42 -0800214 };
215});
216</script>