12da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// Use of this source code is governed by a BSD-style license that can be
32da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// found in the LICENSE file.
42da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
52da489cd246702bee5938545b18a6f710ed214bcJamie Gennis'use strict';
62da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
788448d9ae4dfff1805045790ef5f32495d62abccJeff Brownbase.requireStylesheet('tracks.canvas_based_track');
888448d9ae4dfff1805045790ef5f32495d62abccJeff Brownbase.require('tracks.track');
92da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('fast_rect_renderer');
1088448d9ae4dfff1805045790ef5f32495d62abccJeff Brownbase.require('color_scheme');
112da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('ui');
122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1388448d9ae4dfff1805045790ef5f32495d62abccJeff Brownbase.exportTo('tracing.tracks', function() {
142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis  /**
162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis   * A canvas-based track constructed. Provides the basic heading and
172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis   * invalidation-managment infrastructure. Subclasses must implement drawing
182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis   * and picking code.
192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis   * @constructor
202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis   * @extends {HTMLDivElement}
212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis   */
2288448d9ae4dfff1805045790ef5f32495d62abccJeff Brown  var CanvasBasedTrack =
2388448d9ae4dfff1805045790ef5f32495d62abccJeff Brown      tracing.ui.define(tracing.tracks.Track);
242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
2588448d9ae4dfff1805045790ef5f32495d62abccJeff Brown  CanvasBasedTrack.prototype = {
2688448d9ae4dfff1805045790ef5f32495d62abccJeff Brown    __proto__: tracing.tracks.Track.prototype,
272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    decorate: function() {
2988448d9ae4dfff1805045790ef5f32495d62abccJeff Brown      this.className = 'canvas-based-track';
302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.slices_ = null;
312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.headingDiv_ = document.createElement('div');
3388448d9ae4dfff1805045790ef5f32495d62abccJeff Brown      this.headingDiv_.className = 'canvas-based-track-title';
342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.appendChild(this.headingDiv_);
352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.canvasContainer_ = document.createElement('div');
372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.canvasContainer_.className =
3888448d9ae4dfff1805045790ef5f32495d62abccJeff Brown          'canvas-based-track-canvas-container';
392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.appendChild(this.canvasContainer_);
402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.canvas_ = document.createElement('canvas');
4188448d9ae4dfff1805045790ef5f32495d62abccJeff Brown      this.canvas_.className = 'canvas-based-track-canvas';
422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.canvasContainer_.appendChild(this.canvas_);
432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.ctx_ = this.canvas_.getContext('2d');
452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    detach: function() {
482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (this.viewport_) {
492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.viewport_.removeEventListener('change',
502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                           this.viewportChangeBoundToThis_);
512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.viewport_.removeEventListener('markersChange',
522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            this.viewportMarkersChangeBoundToThis_);
532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      }
542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    set headingWidth(width) {
572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.headingDiv_.style.width = width;
582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    get heading() {
612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      return this.headingDiv_.textContent;
622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    set heading(text) {
652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.headingDiv_.textContent = text;
662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    set tooltip(text) {
692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.headingDiv_.title = text;
702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    get viewport() {
732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      return this.viewport_;
742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    set viewport(v) {
772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.viewport_ = v;
782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (this.viewport_) {
792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.viewport_.removeEventListener('change',
802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                           this.viewportChangeBoundToThis_);
812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.viewport_.removeEventListener('markersChange',
822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            this.viewportMarkersChangeBoundToThis_);
832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      }
842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.viewport_ = v;
852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (this.viewport_) {
862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.viewportChangeBoundToThis_ = this.viewportChange_.bind(this);
872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.viewport_.addEventListener('change',
882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                        this.viewportChangeBoundToThis_);
892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.viewportMarkersChangeBoundToThis_ =
902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis            this.viewportMarkersChange_.bind(this);
912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.viewport_.addEventListener('markersChange',
922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis                                        this.viewportMarkersChangeBoundToThis_);
932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        if (this.isAttachedToDocument_)
942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          this.updateCanvasSizeIfNeeded_();
952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      }
962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.invalidate();
972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    viewportChange_: function() {
1002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.invalidate();
1012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
1022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    viewportMarkersChange_: function() {
1042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (this.viewport_.markers.length < 2)
1054849cead45edf85cf2a61526c0b716eb637f74baJeff Brown        this.classList.remove('ruler-track-with-distance-measurements');
1062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      else
1074849cead45edf85cf2a61526c0b716eb637f74baJeff Brown        this.classList.add('ruler-track-with-distance-measurements');
1082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
1092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    invalidate: function() {
1112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (this.rafPending_)
1122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        return;
1132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      webkitRequestAnimationFrame(function() {
1142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.rafPending_ = false;
1152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        if (!this.viewport_)
1162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          return;
1172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.updateCanvasSizeIfNeeded_();
1182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.redraw();
1192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      }.bind(this), this);
1202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      this.rafPending_ = true;
1212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
1222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    /**
1242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * @return {boolean} Whether the current timeline is attached to the
1252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     * document.
1262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis     */
1272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    get isAttachedToDocument_() {
1282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var cur = this.parentNode;
1292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (!cur)
1302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        return;
1312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      while (cur.parentNode)
1322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        cur = cur.parentNode;
1332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      return cur == this.ownerDocument;
1342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
1352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    updateCanvasSizeIfNeeded_: function() {
1382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var style = window.getComputedStyle(this.canvasContainer_);
1392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var innerWidth = parseInt(style.width) -
1402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          parseInt(style.paddingLeft) - parseInt(style.paddingRight) -
1412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          parseInt(style.borderLeftWidth) - parseInt(style.borderRightWidth);
1422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var innerHeight = parseInt(style.height) -
1432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          parseInt(style.paddingTop) - parseInt(style.paddingBottom) -
1442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis          parseInt(style.borderTopWidth) - parseInt(style.borderBottomWidth);
1452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      var pixelRatio = window.devicePixelRatio || 1;
1462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (this.canvas_.width != innerWidth) {
1472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.canvas_.width = innerWidth * pixelRatio;
1482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.canvas_.style.width = innerWidth + 'px';
1492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      }
1502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      if (this.canvas_.height != innerHeight) {
1512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.canvas_.height = innerHeight * pixelRatio;
1522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis        this.canvas_.style.height = innerHeight + 'px';
1532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      }
1542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    },
1552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    get firstCanvas() {
1562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis      return this.canvas_;
1572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis    }
1582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis  };
1592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis
1602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis  return {
16188448d9ae4dfff1805045790ef5f32495d62abccJeff Brown    CanvasBasedTrack: CanvasBasedTrack
1622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis  };
1632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis});
164