diff options
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.js | 966 |
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 - }; -}); |