// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
/**
* @fileoverview Code for the viewport.
*/
base.require('range');
base.require('event_target');
base.exportTo('tracing', function() {
function SelectionSliceHit(track, slice) {
this.track = track;
this.slice = slice;
}
SelectionSliceHit.prototype = {
get selected() {
return this.slice.selected;
},
set selected(v) {
this.slice.selected = v;
}
};
function SelectionCounterSampleHit(track, counter, sampleIndex) {
this.track = track;
this.counter = counter;
this.sampleIndex = sampleIndex;
}
SelectionCounterSampleHit.prototype = {
get selected() {
return this.track.selectedSamples[this.sampleIndex] == true;
},
set selected(v) {
if (v)
this.track.selectedSamples[this.sampleIndex] = true;
else
this.track.selectedSamples[this.sampleIndex] = false;
this.track.invalidate();
}
};
/**
* Represents a selection within a and its associated set of tracks.
* @constructor
*/
function Selection() {
this.bounds_dirty_ = true;
this.bounds_ = new base.Range();
this.length_ = 0;
}
Selection.prototype = {
__proto__: Object.prototype,
get bounds() {
if (this.bounds_dirty_) {
this.bounds_.reset();
for (var i = 0; i < this.length_; i++) {
var hit = this[i];
if (hit.slice) {
this.bounds_.addValue(hit.slice.start);
this.bounds_.addValue(hit.slice.end);
}
}
this.bounds_dirty_ = false;
}
return this.bounds_;
},
get duration() {
if (this.bounds_.isEmpty)
return 0;
return this.bounds_.max - this.bounds_.min;
},
get length() {
return this.length_;
},
clear: function() {
for (var i = 0; i < this.length_; ++i)
delete this[i];
this.length_ = 0;
this.bounds_dirty_ = true;
},
pushHit: function(hit) {
this.push_(hit);
},
push_: function(hit) {
this[this.length_++] = hit;
this.bounds_dirty_ = true;
return hit;
},
addSlice: function(track, slice) {
return this.push_(new SelectionSliceHit(track, slice));
},
addCounterSample: function(track, counter, sampleIndex) {
return this.push_(
new SelectionCounterSampleHit(
track, counter, sampleIndex));
},
subSelection: function(index, count) {
count = count || 1;
var selection = new Selection();
selection.bounds_dirty_ = true;
if (index < 0 || index + count > this.length_)
throw new Error('Index out of bounds');
for (var i = index; i < index + count; i++)
selection.push_(this[i]);
return selection;
},
getCounterSampleHitsAsSelection: function() {
var selection = new Selection();
for (var i = 0; i < this.length_; i++)
if (this[i] instanceof SelectionCounterSampleHit)
selection.push_(this[i]);
return selection;
},
getSliceHitsAsSelection: function() {
var selection = new Selection();
for (var i = 0; i < this.length_; i++)
if (this[i] instanceof SelectionSliceHit)
selection.push_(this[i]);
return selection;
},
getNumSliceHits: function() {
var numHits = 0;
for (var i = 0; i < this.length_; i++)
if (this[i] instanceof SelectionSliceHit)
numHits++;
return numHits;
},
getNumCounterHits: function() {
var numHits = 0;
for (var i = 0; i < this.length_; i++)
if (this[i] instanceof SelectionCounterSampleHit)
numHits++;
return numHits;
},
map: function(fn) {
for (var i = 0; i < this.length_; i++)
fn(this[i]);
},
/**
* Helper for selection previous or next.
* @param {boolean} forwardp If true, select one forward (next).
* Else, select previous.
* @return {boolean} true if current selection changed.
*/
getShiftedSelection: function(offset) {
var newSelection = new Selection();
for (var i = 0; i < this.length_; i++) {
var hit = this[i];
hit.track.addItemNearToProvidedHitToSelection(
hit, offset, newSelection);
}
if (newSelection.length == 0)
return undefined;
return newSelection;
}
};
return {
SelectionSliceHit: SelectionSliceHit,
SelectionCounterSampleHit: SelectionCounterSampleHit,
Selection: Selection
};
});