summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/trace-viewer/src/tracing/timeline_track_view.js
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/trace-viewer/src/tracing/timeline_track_view.js')
-rw-r--r--chromium/third_party/trace-viewer/src/tracing/timeline_track_view.js966
1 files changed, 0 insertions, 966 deletions
diff --git a/chromium/third_party/trace-viewer/src/tracing/timeline_track_view.js b/chromium/third_party/trace-viewer/src/tracing/timeline_track_view.js
deleted file mode 100644
index 40a82aec5bb..00000000000
--- a/chromium/third_party/trace-viewer/src/tracing/timeline_track_view.js
+++ /dev/null
@@ -1,966 +0,0 @@
-// 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 Interactive visualizaiton of TraceModel objects
- * based loosely on gantt charts. Each thread in the TraceModel is given a
- * set of Tracks, one per subrow in the thread. The TimelineTrackView class
- * acts as a controller, creating the individual tracks, while Tracks
- * do actual drawing.
- *
- * Visually, the TimelineTrackView produces (prettier) visualizations like the
- * following:
- * Thread1: AAAAAAAAAA AAAAA
- * BBBB BB
- * Thread2: CCCCCC CCCCC
- *
- */
-base.requireStylesheet('ui.trace_viewer');
-base.requireStylesheet('tracing.timeline_track_view');
-base.require('base.events');
-base.require('base.properties');
-base.require('base.settings');
-base.require('tracing.filter');
-base.require('tracing.selection');
-base.require('tracing.timeline_viewport');
-base.require('tracing.timeline_display_transform_animations');
-base.require('tracing.timing_tool');
-base.require('tracing.trace_model.event');
-base.require('tracing.tracks.drawing_container');
-base.require('tracing.tracks.trace_model_track');
-base.require('tracing.tracks.ruler_track');
-base.require('ui');
-base.require('ui.mouse_mode_selector');
-
-base.exportTo('tracing', function() {
-
- var Selection = tracing.Selection;
- var SelectionState = tracing.trace_model.SelectionState;
- var Viewport = tracing.TimelineViewport;
-
- var tempDisplayTransform = new tracing.TimelineDisplayTransform();
-
- function intersectRect_(r1, r2) {
- var results = new Object;
- if (r2.left > r1.right || r2.right < r1.left ||
- r2.top > r1.bottom || r2.bottom < r1.top) {
- return false;
- }
- results.left = Math.max(r1.left, r2.left);
- results.top = Math.max(r1.top, r2.top);
- results.right = Math.min(r1.right, r2.right);
- results.bottom = Math.min(r1.bottom, r2.bottom);
- results.width = (results.right - results.left);
- results.height = (results.bottom - results.top);
- return results;
- }
-
- /**
- * Renders a TraceModel into a div element, making one
- * Track for each subrow in each thread of the model, managing
- * overall track layout, and handling user interaction with the
- * viewport.
- *
- * @constructor
- * @extends {HTMLDivElement}
- */
- var TimelineTrackView = ui.define('div');
-
- TimelineTrackView.prototype = {
- __proto__: HTMLDivElement.prototype,
-
- model_: null,
-
- decorate: function() {
-
- this.classList.add('timeline-track-view');
-
- this.viewport_ = new Viewport(this);
- this.viewportDisplayTransformAtMouseDown_ = null;
-
- this.rulerTrackContainer_ =
- new tracing.tracks.DrawingContainer(this.viewport_);
- this.appendChild(this.rulerTrackContainer_);
- this.rulerTrackContainer_.invalidate();
-
- this.rulerTrack_ = new tracing.tracks.RulerTrack(this.viewport_);
- this.rulerTrackContainer_.appendChild(this.rulerTrack_);
-
- this.modelTrackContainer_ =
- new tracing.tracks.DrawingContainer(this.viewport_);
- this.appendChild(this.modelTrackContainer_);
- this.modelTrackContainer_.style.display = 'block';
- this.modelTrackContainer_.invalidate();
-
- this.viewport_.modelTrackContainer = this.modelTrackContainer_;
-
- this.modelTrack_ = new tracing.tracks.TraceModelTrack(this.viewport_);
- this.modelTrackContainer_.appendChild(this.modelTrack_);
-
- this.timingTool_ = new tracing.TimingTool(this.viewport_,
- this);
-
- this.initMouseModeSelector();
-
- this.dragBox_ = this.ownerDocument.createElement('div');
- this.dragBox_.className = 'drag-box';
- this.appendChild(this.dragBox_);
- this.hideDragBox_();
-
- this.bindEventListener_(document, 'keypress', this.onKeypress_, this);
- this.bindEventListener_(document, 'keydown', this.onKeydown_, this);
- this.bindEventListener_(document, 'keyup', this.onKeyup_, this);
-
- this.bindEventListener_(this, 'dblclick', this.onDblClick_, this);
- this.bindEventListener_(this, 'mousewheel', this.onMouseWheel_, this);
-
- this.addEventListener('mousemove', this.onMouseMove_);
-
- this.mouseViewPosAtMouseDown_ = {x: 0, y: 0};
- this.lastMouseViewPos_ = {x: 0, y: 0};
-
- this.selection_ = new Selection();
- this.highlight_ = new Selection();
-
- this.isPanningAndScanning_ = false;
- this.isZooming_ = false;
- },
-
- /**
- * Wraps the standard addEventListener but automatically binds the provided
- * func to the provided target, tracking the resulting closure. When detach
- * is called, these listeners will be automatically removed.
- */
- bindEventListener_: function(object, event, func, target) {
- if (!this.boundListeners_)
- this.boundListeners_ = [];
- var boundFunc = func.bind(target);
- this.boundListeners_.push({object: object,
- event: event,
- boundFunc: boundFunc});
- object.addEventListener(event, boundFunc);
- },
-
- initMouseModeSelector: function() {
- this.mouseModeSelector_ = new ui.MouseModeSelector(this);
- this.appendChild(this.mouseModeSelector_);
-
- this.mouseModeSelector_.addEventListener('beginpan',
- this.onBeginPanScan_.bind(this));
- this.mouseModeSelector_.addEventListener('updatepan',
- this.onUpdatePanScan_.bind(this));
- this.mouseModeSelector_.addEventListener('endpan',
- this.onEndPanScan_.bind(this));
-
- this.mouseModeSelector_.addEventListener('beginselection',
- this.onBeginSelection_.bind(this));
- this.mouseModeSelector_.addEventListener('updateselection',
- this.onUpdateSelection_.bind(this));
- this.mouseModeSelector_.addEventListener('endselection',
- this.onEndSelection_.bind(this));
-
- this.mouseModeSelector_.addEventListener('beginzoom',
- this.onBeginZoom_.bind(this));
- this.mouseModeSelector_.addEventListener('updatezoom',
- this.onUpdateZoom_.bind(this));
- this.mouseModeSelector_.addEventListener('endzoom',
- this.onEndZoom_.bind(this));
-
- this.mouseModeSelector_.addEventListener('entertiming',
- this.timingTool_.onEnterTiming.bind(this.timingTool_));
- this.mouseModeSelector_.addEventListener('begintiming',
- this.timingTool_.onBeginTiming.bind(this.timingTool_));
- this.mouseModeSelector_.addEventListener('updatetiming',
- this.timingTool_.onUpdateTiming.bind(this.timingTool_));
- this.mouseModeSelector_.addEventListener('endtiming',
- this.timingTool_.onEndTiming.bind(this.timingTool_));
- this.mouseModeSelector_.addEventListener('exittiming',
- this.timingTool_.onExitTiming.bind(this.timingTool_));
-
- var m = ui.MOUSE_SELECTOR_MODE;
- this.mouseModeSelector_.supportedModeMask =
- m.SELECTION | m.PANSCAN | m.ZOOM | m.TIMING;
- this.mouseModeSelector_.settingsKey =
- 'timelineTrackView.mouseModeSelector';
- this.mouseModeSelector_.setKeyCodeForMode(m.PANSCAN, '2'.charCodeAt(0));
- this.mouseModeSelector_.setKeyCodeForMode(m.SELECTION, '1'.charCodeAt(0));
- this.mouseModeSelector_.setKeyCodeForMode(m.ZOOM, '3'.charCodeAt(0));
- this.mouseModeSelector_.setKeyCodeForMode(m.TIMING, '4'.charCodeAt(0));
-
- this.mouseModeSelector_.setModifierForAlternateMode(
- m.SELECTION, ui.MODIFIER.SHIFT);
- this.mouseModeSelector_.setModifierForAlternateMode(
- m.PANSCAN, ui.MODIFIER.SPACE);
- this.mouseModeSelector_.setModifierForAlternateMode(
- m.ZOOM, ui.MODIFIER.CMD_OR_CTRL);
- },
-
- detach: function() {
- this.modelTrack_.detach();
-
- for (var i = 0; i < this.boundListeners_.length; i++) {
- var binding = this.boundListeners_[i];
- binding.object.removeEventListener(binding.event, binding.boundFunc);
- }
- this.boundListeners_ = undefined;
- this.viewport_.detach();
- },
-
- get viewport() {
- return this.viewport_;
- },
-
- get model() {
- return this.model_;
- },
-
- set model(model) {
- if (!model)
- throw new Error('Model cannot be null');
-
- var modelInstanceChanged = this.model_ != model;
- this.model_ = model;
- this.modelTrack_.model = model;
-
- // Set up a reasonable viewport.
- if (modelInstanceChanged)
- this.viewport_.setWhenPossible(this.setInitialViewport_.bind(this));
-
- base.setPropertyAndDispatchChange(this, 'model', model);
- },
-
- get hasVisibleContent() {
- return this.modelTrack_.hasVisibleContent;
- },
-
- setInitialViewport_: function() {
- var w = this.modelTrackContainer_.canvas.width;
-
- var min;
- var range;
-
- if (this.model_.bounds.isEmpty) {
- min = 0;
- range = 1000;
- } else if (this.model_.bounds.range == 0) {
- min = this.model_.bounds.min;
- range = 1000;
- } else {
- min = this.model_.bounds.min;
- range = this.model_.bounds.range;
- }
- var boost = range * 0.15;
- tempDisplayTransform.set(this.viewport.currentDisplayTransform);
- tempDisplayTransform.xSetWorldBounds(min - boost,
- min + range + boost,
- w);
- this.viewport.setDisplayTransformImmediately(tempDisplayTransform);
- },
-
- /**
- * @param {Filter} filter The filter to use for finding matches.
- * @param {Selection} selection The selection to add matches to.
- * @return {Array} An array of objects that match the provided
- * TitleFilter.
- */
- addAllObjectsMatchingFilterToSelection: function(filter, selection) {
- this.modelTrack_.addAllObjectsMatchingFilterToSelection(
- filter, selection);
- },
-
- /**
- * @return {Element} The element whose focused state determines
- * whether to respond to keyboard inputs.
- * Defaults to the parent element.
- */
- get focusElement() {
- if (this.focusElement_)
- return this.focusElement_;
- return this.parentElement;
- },
-
- /**
- * Sets the element whose focus state will determine whether
- * to respond to keybaord input.
- */
- set focusElement(value) {
- this.focusElement_ = value;
- },
-
- get listenToKeys_() {
- if (!this.viewport_.isAttachedToDocument_)
- return false;
- if (this.activeElement instanceof tracing.FindControl)
- return false;
- if (!this.focusElement_)
- return true;
- if (this.focusElement.tabIndex >= 0) {
- if (document.activeElement == this.focusElement)
- return true;
- return ui.elementIsChildOf(document.activeElement, this.focusElement);
- }
- return true;
- },
-
- onMouseMove_: function(e) {
-
- // Zooming requires the delta since the last mousemove so we need to avoid
- // tracking it when the zoom interaction is active.
- if (this.isZooming_)
- return;
-
- this.storeLastMousePos_(e);
- },
-
- onKeypress_: function(e) {
- var vp = this.viewport_;
- if (!this.listenToKeys_)
- return;
- if (document.activeElement.nodeName == 'INPUT')
- return;
- var viewWidth = this.modelTrackContainer_.canvas.clientWidth;
- var curMouseV, curCenterW;
- switch (e.keyCode) {
-
- case 119: // w
- case 44: // ,
- this.zoomBy_(1.5, true);
- break;
- case 115: // s
- case 111: // o
- this.zoomBy_(1 / 1.5, true);
- break;
- case 103: // g
- this.onGridToggle_(true);
- break;
- case 71: // G
- this.onGridToggle_(false);
- break;
- case 87: // W
- case 60: // <
- this.zoomBy_(10, true);
- break;
- case 83: // S
- case 79: // O
- this.zoomBy_(1 / 10, true);
- break;
- case 97: // a
- this.queueSmoothPan_(viewWidth * 0.3, 0);
- break;
- case 100: // d
- case 101: // e
- this.queueSmoothPan_(viewWidth * -0.3, 0);
- break;
- case 65: // A
- this.queueSmoothPan_(viewWidth * 0.5, 0);
- break;
- case 68: // D
- this.queueSmoothPan_(viewWidth * -0.5, 0);
- break;
- case 48: // 0
- this.setInitialViewport_();
- break;
- case 102: // f
- this.zoomToSelection();
- break;
- case 'm'.charCodeAt(0):
- this.putMarkAroundCurrentSelection_();
- break;
- }
- },
-
- // Not all keys send a keypress.
- onKeydown_: function(e) {
- if (!this.listenToKeys_)
- return;
- var sel;
- var vp = this.viewport;
- var viewWidth = this.modelTrackContainer_.canvas.clientWidth;
-
- switch (e.keyCode) {
- case 37: // left arrow
- sel = this.selection.getShiftedSelection(
- this.viewport, -1);
- if (sel) {
- this.setSelectionAndClearHighlight(sel);
- this.panToSelection();
- e.preventDefault();
- } else {
- this.queueSmoothPan_(viewWidth * 0.3, 0);
- }
- break;
- case 39: // right arrow
- sel = this.selection.getShiftedSelection(
- this.viewport, 1);
- if (sel) {
- this.setSelectionAndClearHighlight(sel);
- this.panToSelection();
- e.preventDefault();
- } else {
- this.queueSmoothPan_(-viewWidth * 0.3, 0);
- }
- break;
- case 9: // TAB
- if (this.focusElement.tabIndex == -1) {
- if (e.shiftKey)
- this.selectPrevious_(e);
- else
- this.selectNext_(e);
- e.preventDefault();
- }
- break;
- }
- },
-
- onKeyup_: function(e) {
- if (!this.listenToKeys_)
- return;
- if (!e.shiftKey) {
- if (this.dragBeginEvent_) {
- this.setDragBoxPosition_(this.dragBoxXStart_, this.dragBoxYStart_,
- this.dragBoxXEnd_, this.dragBoxYEnd_);
- }
- }
-
- },
-
- onDblClick_: function(e) {
- if (this.mouseModeSelector_.mode !== ui.MOUSE_SELECTOR_MODE.SELECTION)
- return;
-
- if (!this.selection.length || !this.selection[0].title)
- return;
-
- var selection = new Selection();
- var filter = new tracing.ExactTitleFilter(this.selection[0].title);
- this.addAllObjectsMatchingFilterToSelection(filter, selection);
-
- this.setSelectionAndClearHighlight(selection);
- },
-
- onMouseWheel_: function(e) {
- if (!e.altKey)
- return;
-
- var delta = e.wheelDelta / 120;
- var zoomScale = Math.pow(1.5, delta);
- this.zoomBy_(zoomScale);
- e.preventDefault();
- },
-
- queueSmoothPan_: function(viewDeltaX, deltaY) {
- var deltaX = this.viewport_.currentDisplayTransform.xViewVectorToWorld(
- viewDeltaX);
- var animation = new tracing.TimelineDisplayTransformPanAnimation(
- deltaX, deltaY);
- this.viewport_.queueDisplayTransformAnimation(animation);
- },
-
- /**
- * Zoom in or out on the timeline by the given scale factor.
- * @param {Number} scale The scale factor to apply. If <1, zooms out.
- * @param {boolean} Whether to change the zoom level smoothly.
- */
- zoomBy_: function(scale, smooth) {
- smooth = !!smooth;
- var vp = this.viewport;
- var viewWidth = this.modelTrackContainer_.canvas.clientWidth;
- var pixelRatio = window.devicePixelRatio || 1;
-
- var goalFocalPointXView = this.lastMouseViewPos_.x * pixelRatio;
- var goalFocalPointXWorld = vp.currentDisplayTransform.xViewToWorld(
- goalFocalPointXView);
- if (smooth) {
- var animation = new tracing.TimelineDisplayTransformZoomToAnimation(
- goalFocalPointXWorld, goalFocalPointXView,
- vp.currentDisplayTransform.panY,
- scale);
- vp.queueDisplayTransformAnimation(animation);
- } else {
- tempDisplayTransform.set(vp.currentDisplayTransform);
- tempDisplayTransform.scaleX = tempDisplayTransform.scaleX * scale;
- tempDisplayTransform.xPanWorldPosToViewPos(
- goalFocalPointXWorld, goalFocalPointXView, viewWidth);
- vp.setDisplayTransformImmediately(tempDisplayTransform);
- }
- },
-
- /**
- * Zoom into the current selection.
- */
- zoomToSelection: function() {
- if (!this.selectionOfInterest.length)
- return;
-
- var bounds = this.selectionOfInterest.bounds;
- if (!bounds.range)
- return;
-
- var worldCenter = bounds.center;
- var adjustedWorldRange = bounds.range * 1.25;
- var newScale = this.modelTrackContainer_.canvas.width /
- adjustedWorldRange;
- var zoomInRatio = newScale / this.viewport.currentDisplayTransform.scaleX;
- var animation = new tracing.TimelineDisplayTransformZoomToAnimation(
- worldCenter, 'center',
- this.viewport.currentDisplayTransform.panY,
- zoomInRatio);
- this.viewport.queueDisplayTransformAnimation(animation);
- },
-
- /**
- * Pan the view so the current selection becomes visible.
- */
- panToSelection: function() {
- if (!this.selectionOfInterest.length)
- return;
-
- var bounds = this.selectionOfInterest.bounds;
- var worldCenter = bounds.center;
- var viewWidth = this.modelTrackContainer_.canvas.width;
-
- var dt = this.viewport.currentDisplayTransform;
- if (false && !bounds.range) {
- if (dt.xWorldToView(bounds.center) < 0 ||
- dt.xWorldToView(bounds.center) > viewWidth) {
- tempDisplayTransform.set(dt);
- tempDisplayTransform.xPanWorldPosToViewPos(
- worldCenter, 'center', viewWidth);
- var deltaX = tempDisplayTransform.panX - dt.panX;
- var animation = new tracing.TimelineDisplayTransformPanAnimation(
- deltaX, 0);
- this.viewport.queueDisplayTransformAnimation(animation);
- }
- return;
- }
-
- tempDisplayTransform.set(dt);
- tempDisplayTransform.xPanWorldBoundsIntoView(
- bounds.min,
- bounds.max,
- viewWidth);
- var deltaX = tempDisplayTransform.panX - dt.panX;
- var animation = new tracing.TimelineDisplayTransformPanAnimation(
- deltaX, 0);
- this.viewport.queueDisplayTransformAnimation(animation);
- },
-
- putMarkAroundCurrentSelection_: function() {
- var selectionBounds = this.selection.bounds;
- if (selectionBounds.empty)
- return this.viewport.removeAllMarkers();
- var markerBounds = this.viewport.getMarkerBounds();
-
-
- if (selectionBounds.equals(markerBounds)) {
- return this.viewport.removeAllMarkers();
- }
- this.viewport.removeAllMarkers();
- this.viewport.addMarker(this.viewport.createMarker(selectionBounds.min));
- this.viewport.addMarker(this.viewport.createMarker(selectionBounds.max));
- },
-
- /**
- * Sets the selected events and changes the SelectionState of the events to
- * SELECTED.
- * @param {Selection} selection A Selection of the new selected events.
- */
- set selection(selection) {
- this.setSelectionAndHighlight(selection, this.highlight_);
- },
-
- get selection() {
- return this.selection_;
- },
-
- /**
- * Sets the highlighted events and changes the SelectionState of the events
- * to HIGHLIGHTED. All other events are set to DIMMED, except SELECTED
- * ones.
- * @param {Selection} selection A Selection of the new selected events.
- */
- set highlight(highlight) {
- this.setSelectionAndHighlight(this.selection_, highlight);
- },
-
- get highlight() {
- return this.highlight_;
- },
-
- /**
- * Getter for events of interest, primarily SELECTED and secondarily
- * HIGHLIGHTED events.
- */
- get selectionOfInterest() {
- if (!this.selection_.length && this.highlight_.length)
- return this.highlight_;
- return this.selection_;
- },
-
- /**
- * Sets the selected events, changes the SelectionState of the events to
- * SELECTED and clears the highlighted events.
- * @param {Selection} selection A Selection of the new selected events.
- */
- setSelectionAndClearHighlight: function(selection) {
- this.setSelectionAndHighlight(selection, null);
- },
-
- /**
- * Sets the highlighted events, changes the SelectionState of the events to
- * HIGHLIGHTED and clears the selected events. All other events are set to
- * DIMMED.
- * @param {Selection} highlight A Selection of the new highlighted events.
- */
- setHighlightAndClearSelection: function(highlight) {
- this.setSelectionAndHighlight(null, highlight);
- },
-
- /**
- * Sets both selected and highlighted events. If an event is both it will be
- * set to SELECTED. All other events are set to DIMMED.
- * @param {Selection} selection A Selection of the new selected events.
- * @param {Selection} highlight A Selection of the new highlighted events.
- */
- setSelectionAndHighlight: function(selection, highlight) {
- if (selection === this.selection_ && highlight === this.highlight_)
- return;
-
- if ((selection !== null && !(selection instanceof Selection)) ||
- (highlight !== null && !(highlight instanceof Selection))) {
- throw new Error('Expected Selection');
- }
-
- if (highlight && highlight.length) {
- // Set all events to DIMMED. This needs to be done before clearing the
- // old highlight, so that the old events are still available. This is
- // also necessary when the highlight doesn't change, because it might
- // have overlapping events with selection.
- this.resetEventsTo_(SelectionState.DIMMED);
-
- // Switch the highlight.
- if (highlight !== this.highlight_)
- this.highlight_ = highlight;
-
- // Set HIGHLIGHTED on the events of the new highlight.
- this.setSelectionState_(highlight, SelectionState.HIGHLIGHTED);
- } else {
- // If no highlight is active the SelectionState needs to be cleared.
- // Note that this also clears old SELECTED events, so it doesn't need
- // to be called again when setting the selection.
- this.resetEventsTo_(SelectionState.NONE);
- this.highlight_ = new Selection();
- }
-
- if (selection && selection.length) {
- // Switch the selection
- if (selection !== this.selection_)
- this.selection_ = selection;
-
- // Set SELECTED on the events of the new highlight.
- this.setSelectionState_(selection, SelectionState.SELECTED);
- } else
- this.selection_ = new Selection();
-
- base.dispatchSimpleEvent(this, 'selectionChange');
-
- if (this.selectionOfInterest.length) {
- var track = this.viewport.trackForEvent(this.selectionOfInterest[0]);
- if (track)
- track.scrollIntoViewIfNeeded();
- }
-
- this.viewport.dispatchChangeEvent(); // Triggers a redraw.
- },
-
- /**
- * Sets a new SelectionState on all events in the selection.
- * @param {Selection} selection The affected selection.
- * @param {SelectionState} selectionState The new selection state.
- */
- setSelectionState_: function(selection, selectionState) {
- for (var i = 0; i < selection.length; i++)
- selection[i].selectionState = selectionState;
- },
-
- /**
- * Resets all events to the provided SelectionState. When the SelectionState
- * changes from or to DIMMED all events in the model need to get updated.
- * @param {SelectionState} selectionState The SelectionState to reset to.
- */
- resetEventsTo_: function(selectionState) {
- var dimmed = this.highlight_.length;
- var resetAll = (dimmed && selectionState !== SelectionState.DIMMED) ||
- (!dimmed && selectionState === SelectionState.DIMMED);
- if (resetAll) {
- this.model.iterateAllEvents(
- function(event) { event.selectionState = selectionState; });
- } else {
- this.setSelectionState_(this.selection_, selectionState);
- this.setSelectionState_(this.highlight_, selectionState);
- }
- },
-
- hideDragBox_: function() {
- this.dragBox_.style.left = '-1000px';
- this.dragBox_.style.top = '-1000px';
- this.dragBox_.style.width = 0;
- this.dragBox_.style.height = 0;
- },
-
- setDragBoxPosition_: function(xStart, yStart, xEnd, yEnd) {
- var loY = Math.min(yStart, yEnd);
- var hiY = Math.max(yStart, yEnd);
- var loX = Math.min(xStart, xEnd);
- var hiX = Math.max(xStart, xEnd);
- var modelTrackRect = this.modelTrack_.getBoundingClientRect();
- var dragRect = {left: loX, top: loY, width: hiX - loX, height: hiY - loY};
-
- dragRect.right = dragRect.left + dragRect.width;
- dragRect.bottom = dragRect.top + dragRect.height;
-
- var modelTrackContainerRect =
- this.modelTrackContainer_.getBoundingClientRect();
- var clipRect = {
- left: modelTrackContainerRect.left,
- top: modelTrackContainerRect.top,
- right: modelTrackContainerRect.right,
- bottom: modelTrackContainerRect.bottom
- };
-
- var headingWidth = window.getComputedStyle(
- this.querySelector('heading')).width;
- var trackTitleWidth = parseInt(headingWidth);
- clipRect.left = clipRect.left + trackTitleWidth;
-
- var finalDragBox = intersectRect_(clipRect, dragRect);
-
- this.dragBox_.style.left = finalDragBox.left + 'px';
- this.dragBox_.style.width = finalDragBox.width + 'px';
- this.dragBox_.style.top = finalDragBox.top + 'px';
- this.dragBox_.style.height = finalDragBox.height + 'px';
-
- var pixelRatio = window.devicePixelRatio || 1;
- var canv = this.modelTrackContainer_.canvas;
- var dt = this.viewport.currentDisplayTransform;
- var loWX = dt.xViewToWorld(
- (loX - canv.offsetLeft) * pixelRatio);
- var hiWX = dt.xViewToWorld(
- (hiX - canv.offsetLeft) * pixelRatio);
-
- var roundedDuration = Math.round((hiWX - loWX) * 100) / 100;
- this.dragBox_.textContent = roundedDuration + 'ms';
-
- var e = new base.Event('selectionChanging');
- e.loWX = loWX;
- e.hiWX = hiWX;
- this.dispatchEvent(e);
- },
-
- onGridToggle_: function(left) {
- var tb = left ? this.selection.bounds.min : this.selection.bounds.max;
-
- // Toggle the grid off if the grid is on, the marker position is the same
- // and the same element is selected (same timebase).
- if (this.viewport.gridEnabled &&
- this.viewport.gridSide === left &&
- this.viewport.gridInitialTimebase === tb) {
- this.viewport.gridside = undefined;
- this.viewport.gridEnabled = false;
- this.viewport.gridInitialTimebase = undefined;
- return;
- }
-
- // Shift the timebase left until its just left of model_.bounds.min.
- var numIntervalsSinceStart = Math.ceil((tb - this.model_.bounds.min) /
- this.viewport.gridStep_);
-
- this.viewport.gridEnabled = true;
- this.viewport.gridSide = left;
- this.viewport.gridInitialTimebase = tb;
- this.viewport.gridTimebase = tb -
- (numIntervalsSinceStart + 1) * this.viewport.gridStep_;
- },
-
- storeLastMousePos_: function(e) {
- this.lastMouseViewPos_ = this.extractRelativeMousePosition_(e);
- },
-
- extractRelativeMousePosition_: function(e) {
- var canv = this.modelTrackContainer_.canvas;
- return {
- x: e.clientX - canv.offsetLeft,
- y: e.clientY - canv.offsetTop
- };
- },
-
- storeInitialMouseDownPos_: function(e) {
-
- var position = this.extractRelativeMousePosition_(e);
-
- this.mouseViewPosAtMouseDown_.x = position.x;
- this.mouseViewPosAtMouseDown_.y = position.y;
- },
-
- focusElements_: function() {
- if (document.activeElement)
- document.activeElement.blur();
- if (this.focusElement.tabIndex >= 0)
- this.focusElement.focus();
- },
-
- storeInitialInteractionPositionsAndFocus_: function(e) {
-
- this.storeInitialMouseDownPos_(e);
- this.storeLastMousePos_(e);
-
- this.focusElements_();
- },
-
- onBeginPanScan_: function(e) {
- var vp = this.viewport;
- this.viewportDisplayTransformAtMouseDown_ =
- vp.currentDisplayTransform.clone();
- this.isPanningAndScanning_ = true;
-
- this.storeInitialInteractionPositionsAndFocus_(e);
- e.preventDefault();
- },
-
- onUpdatePanScan_: function(e) {
- if (!this.isPanningAndScanning_)
- return;
-
- var viewWidth = this.modelTrackContainer_.canvas.clientWidth;
-
- var pixelRatio = window.devicePixelRatio || 1;
- var xDeltaView = pixelRatio * (this.lastMouseViewPos_.x -
- this.mouseViewPosAtMouseDown_.x);
-
- var yDelta = this.lastMouseViewPos_.y -
- this.mouseViewPosAtMouseDown_.y;
-
- tempDisplayTransform.set(this.viewportDisplayTransformAtMouseDown_);
- tempDisplayTransform.incrementPanXInViewUnits(xDeltaView);
- tempDisplayTransform.panY -= yDelta;
- this.viewport.setDisplayTransformImmediately(tempDisplayTransform);
-
- e.preventDefault();
- e.stopPropagation();
-
- this.storeLastMousePos_(e);
- },
-
- onEndPanScan_: function(e) {
- this.isPanningAndScanning_ = false;
-
- this.storeLastMousePos_(e);
-
- if (!e.isClick)
- e.preventDefault();
- },
-
- onBeginSelection_: function(e) {
- var canv = this.modelTrackContainer_.canvas;
- var rect = this.modelTrack_.getBoundingClientRect();
- var canvRect = canv.getBoundingClientRect();
-
- var inside = rect &&
- e.clientX >= rect.left &&
- e.clientX < rect.right &&
- e.clientY >= rect.top &&
- e.clientY < rect.bottom &&
- e.clientX >= canvRect.left &&
- e.clientX < canvRect.right;
-
- if (!inside)
- return;
-
- this.dragBeginEvent_ = e;
-
- this.storeInitialInteractionPositionsAndFocus_(e);
- e.preventDefault();
- },
-
- onUpdateSelection_: function(e) {
- if (!this.dragBeginEvent_)
- return;
-
- // Update the drag box
- this.dragBoxXStart_ = this.dragBeginEvent_.clientX;
- this.dragBoxXEnd_ = e.clientX;
- this.dragBoxYStart_ = this.dragBeginEvent_.clientY;
- this.dragBoxYEnd_ = e.clientY;
- this.setDragBoxPosition_(this.dragBoxXStart_, this.dragBoxYStart_,
- this.dragBoxXEnd_, this.dragBoxYEnd_);
-
- },
-
- onEndSelection_: function(e) {
- e.preventDefault();
-
- if (!this.dragBeginEvent_)
- return;
-
- // Stop the dragging.
- this.hideDragBox_();
- var eDown = this.dragBeginEvent_;
- this.dragBeginEvent_ = null;
-
- // Figure out extents of the drag.
- var loY = Math.min(eDown.clientY, e.clientY);
- var hiY = Math.max(eDown.clientY, e.clientY);
- var loX = Math.min(eDown.clientX, e.clientX);
- var hiX = Math.max(eDown.clientX, e.clientX);
- var tracksContainerBoundingRect =
- this.modelTrackContainer_.getBoundingClientRect();
- var topBoundary = tracksContainerBoundingRect.height;
-
- // Convert to worldspace.
- var canv = this.modelTrackContainer_.canvas;
- var loVX = loX - canv.offsetLeft;
- var hiVX = hiX - canv.offsetLeft;
-
- // Figure out what has been selected.
- var selection = new Selection();
- this.modelTrack_.addIntersectingItemsInRangeToSelection(
- loVX, hiVX, loY, hiY, selection);
-
- // Activate the new selection.
- this.setSelectionAndClearHighlight(selection);
- },
-
- onBeginZoom_: function(e) {
- this.isZooming_ = true;
-
- this.storeInitialInteractionPositionsAndFocus_(e);
- e.preventDefault();
- },
-
- onUpdateZoom_: function(e) {
- if (!this.isZooming_)
- return;
- var newPosition = this.extractRelativeMousePosition_(e);
-
- var zoomScaleValue = 1 + (this.lastMouseViewPos_.y -
- newPosition.y) * 0.01;
-
- this.zoomBy_(zoomScaleValue, false);
- this.storeLastMousePos_(e);
- },
-
- onEndZoom_: function(e) {
- this.isZooming_ = false;
-
- if (!e.isClick)
- e.preventDefault();
- }
- };
-
- return {
- TimelineTrackView: TimelineTrackView
- };
-});