morpheus.TrackSelection = function(track, positions, selectionModel, isColumns, controller) { var canvas = track.canvas; var startIndex = -1; var coord = isColumns ? 'x' : 'y'; function getPosition(event, useDelta) { if (track.settings.squished) { var total = positions.getPosition(positions.getLength() - 1) + positions.getItemSize(positions.getLength() - 1); var squishFactor = total / (isColumns ? track.getUnscaledWidth() : track .getUnscaledHeight()); var clientXY = morpheus.CanvasUtil.getClientXY(event, useDelta); var p = morpheus.CanvasUtil.getMousePosWithScroll(event.target, event, 0, 0, useDelta); p[coord] *= squishFactor; return p; } else { return morpheus.CanvasUtil.getMousePosWithScroll(event.target, event, controller.scrollLeft(), controller.scrollTop(), useDelta); } } this.hammer = morpheus.Util .hammer(canvas, [ 'pan', 'tap', 'longpress' ]) .on('longpress', function(event) { event.preventDefault(); event.srcEvent.stopImmediatePropagation(); event.srcEvent.stopPropagation(); controller.setSelectedTrack(track.name, isColumns); track.showPopup(event.srcEvent); }) .on( 'panmove', function(event) { var position = getPosition(event); var endIndex = positions.getIndex(position[coord], false); var commandKey = morpheus.Util.IS_MAC ? event.srcEvent.metaKey : event.srcEvent.ctrlKey; var viewIndices = commandKey ? selectionModel .getViewIndices() : new morpheus.Set(); var _startIndex = startIndex; if (startIndex > endIndex) { var tmp = endIndex; endIndex = _startIndex; _startIndex = tmp; } for (var i = _startIndex; i <= endIndex; i++) { viewIndices.add(i); } selectionModel.setViewIndices(viewIndices, true); if (!isColumns) { var scrollTop = controller.scrollTop(); var scrollBottom = scrollTop + controller.heatmap.getUnscaledHeight(); if (position.y > scrollBottom) { controller.scrollTop(scrollTop + 8); } else if (position.y < scrollTop) { controller.scrollTop(scrollTop - 8); } } else { var scrollLeft = controller.scrollLeft(); var scrollRight = scrollLeft + controller.heatmap.getUnscaledWidth(); if (position.x > scrollRight) { controller.scrollLeft(scrollLeft + 8); } else if (position.x < scrollLeft) { controller.scrollLeft(scrollLeft - 8); } } event.preventDefault(); event.srcEvent.stopPropagation(); event.srcEvent.stopImmediatePropagation(); }) .on('panstart', function(event) { controller.setSelectedTrack(track.name, isColumns); var position = getPosition(event, true); startIndex = positions.getIndex(position[coord], false); }) .on( 'tap doubletap', function(event) { var position = getPosition(event); var index = positions.getIndex(position[coord], false); if (event.tapCount > 1) { if ((isColumns && !controller.options.columnsSortable) || (!isColumns && !controller.options.rowsSortable)) { return; } // var viewIndices = new morpheus.Set(); // viewIndices.add(index); // selectionModel.setViewIndices(viewIndices, // false); controller.sortBasedOnSelection(null, isColumns, event.srcEvent.shiftKey); } else { controller.setSelectedTrack(track.name, isColumns); var commandKey = morpheus.Util.IS_MAC ? event.srcEvent.metaKey : event.srcEvent.ctrlKey; if (morpheus.Util.IS_MAC && event.srcEvent.ctrlKey) { // right-click // on // Mac return; } var viewIndices; if (commandKey) { // toggle selection viewIndices = selectionModel.getViewIndices(); if (viewIndices.has(index)) { viewIndices.remove(index); } else { viewIndices.add(index); } } else if (event.srcEvent.shiftKey) { // add to // selection viewIndices = selectionModel.getViewIndices(); var min = Number.MAX_VALUE; var max = -Number.MAX_VALUE; for ( var viewIndex in viewIndices) { min = Math.min(viewIndex, min); max = Math.max(viewIndex, max); } if (index >= max) { // select from index to max for (var i = max; i <= index; i++) { viewIndices.add(i); } } else {// select from index to min for (var i = Math.min(index, min), max = Math .max(index, min); i <= max; i++) { viewIndices.add(i); } } } else { viewIndices = new morpheus.Set(); viewIndices.add(index); } selectionModel.setViewIndices(viewIndices, true); } }); }; morpheus.TrackSelection.prototype = { dispose : function() { this.hammer.destroy(); } };