Home | History | Annotate | Download | only in src
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 'use strict';
      6 
      7 /**
      8  * @fileoverview Code for the viewport.
      9  */
     10 base.require('range');
     11 base.require('event_target');
     12 base.exportTo('tracing', function() {
     13 
     14   function SelectionSliceHit(track, slice) {
     15     this.track = track;
     16     this.slice = slice;
     17   }
     18   SelectionSliceHit.prototype = {
     19     get selected() {
     20       return this.slice.selected;
     21     },
     22     set selected(v) {
     23       this.slice.selected = v;
     24     }
     25   };
     26 
     27   function SelectionCounterSampleHit(track, counter, sampleIndex) {
     28     this.track = track;
     29     this.counter = counter;
     30     this.sampleIndex = sampleIndex;
     31   }
     32   SelectionCounterSampleHit.prototype = {
     33     get selected() {
     34       return this.track.selectedSamples[this.sampleIndex] == true;
     35     },
     36     set selected(v) {
     37       if (v)
     38         this.track.selectedSamples[this.sampleIndex] = true;
     39       else
     40         this.track.selectedSamples[this.sampleIndex] = false;
     41       this.track.invalidate();
     42     }
     43   };
     44 
     45 
     46   /**
     47    * Represents a selection within a  and its associated set of tracks.
     48    * @constructor
     49    */
     50   function Selection() {
     51     this.bounds_dirty_ = true;
     52     this.bounds_ = new base.Range();
     53     this.length_ = 0;
     54   }
     55   Selection.prototype = {
     56     __proto__: Object.prototype,
     57 
     58     get bounds() {
     59       if (this.bounds_dirty_) {
     60         this.bounds_.reset();
     61         for (var i = 0; i < this.length_; i++) {
     62           var hit = this[i];
     63           if (hit.slice) {
     64             this.bounds_.addValue(hit.slice.start);
     65             this.bounds_.addValue(hit.slice.end);
     66           }
     67         }
     68         this.bounds_dirty_ = false;
     69       }
     70       return this.bounds_;
     71     },
     72 
     73     get duration() {
     74       if (this.bounds_.isEmpty)
     75         return 0;
     76       return this.bounds_.max - this.bounds_.min;
     77     },
     78 
     79     get length() {
     80       return this.length_;
     81     },
     82 
     83     clear: function() {
     84       for (var i = 0; i < this.length_; ++i)
     85         delete this[i];
     86       this.length_ = 0;
     87       this.bounds_dirty_ = true;
     88     },
     89 
     90     pushHit: function(hit) {
     91       this.push_(hit);
     92     },
     93 
     94     push_: function(hit) {
     95       this[this.length_++] = hit;
     96       this.bounds_dirty_ = true;
     97       return hit;
     98     },
     99 
    100     addSlice: function(track, slice) {
    101       return this.push_(new SelectionSliceHit(track, slice));
    102     },
    103 
    104     addCounterSample: function(track, counter, sampleIndex) {
    105       return this.push_(
    106           new SelectionCounterSampleHit(
    107           track, counter, sampleIndex));
    108     },
    109 
    110     subSelection: function(index, count) {
    111       count = count || 1;
    112 
    113       var selection = new Selection();
    114       selection.bounds_dirty_ = true;
    115       if (index < 0 || index + count > this.length_)
    116         throw new Error('Index out of bounds');
    117 
    118       for (var i = index; i < index + count; i++)
    119         selection.push_(this[i]);
    120 
    121       return selection;
    122     },
    123 
    124     getCounterSampleHitsAsSelection: function() {
    125       var selection = new Selection();
    126       for (var i = 0; i < this.length_; i++)
    127         if (this[i] instanceof SelectionCounterSampleHit)
    128           selection.push_(this[i]);
    129       return selection;
    130     },
    131 
    132     getSliceHitsAsSelection: function() {
    133       var selection = new Selection();
    134       for (var i = 0; i < this.length_; i++)
    135         if (this[i] instanceof SelectionSliceHit)
    136           selection.push_(this[i]);
    137       return selection;
    138     },
    139 
    140     getNumSliceHits: function() {
    141       var numHits = 0;
    142       for (var i = 0; i < this.length_; i++)
    143         if (this[i] instanceof SelectionSliceHit)
    144           numHits++;
    145       return numHits;
    146     },
    147 
    148     getNumCounterHits: function() {
    149       var numHits = 0;
    150       for (var i = 0; i < this.length_; i++)
    151         if (this[i] instanceof SelectionCounterSampleHit)
    152           numHits++;
    153       return numHits;
    154     },
    155 
    156     map: function(fn) {
    157       for (var i = 0; i < this.length_; i++)
    158         fn(this[i]);
    159     },
    160 
    161     /**
    162      * Helper for selection previous or next.
    163      * @param {boolean} forwardp If true, select one forward (next).
    164      *   Else, select previous.
    165      * @return {boolean} true if current selection changed.
    166      */
    167     getShiftedSelection: function(offset) {
    168       var newSelection = new Selection();
    169       for (var i = 0; i < this.length_; i++) {
    170         var hit = this[i];
    171         hit.track.addItemNearToProvidedHitToSelection(
    172             hit, offset, newSelection);
    173       }
    174 
    175       if (newSelection.length == 0)
    176         return undefined;
    177       return newSelection;
    178     }
    179   };
    180 
    181   return {
    182     SelectionSliceHit: SelectionSliceHit,
    183     SelectionCounterSampleHit: SelectionCounterSampleHit,
    184     Selection: Selection
    185   };
    186 });
    187