Merge branch 'master' into table-export-934

This commit is contained in:
Victor Woeltjen 2016-05-26 10:42:35 -07:00
commit d15d27af73
6 changed files with 113 additions and 54 deletions

View File

@ -38,7 +38,6 @@ define(
function InfoGestureButton($document, agentService, infoService, element, domainObject) { function InfoGestureButton($document, agentService, infoService, element, domainObject) {
var dismissBubble, var dismissBubble,
touchPosition, touchPosition,
scopeOff,
body = $document.find('body'); body = $document.find('body');
function trackPosition(event) { function trackPosition(event) {
@ -94,10 +93,6 @@ define(
element.on('click', showBubble); element.on('click', showBubble);
} }
// Also make sure we dismiss bubble if representation is destroyed
// before the mouse actually leaves it
scopeOff = element.scope().$on('$destroy', hideBubble);
return { return {
/** /**
* Detach any event handlers associated with this gesture. * Detach any event handlers associated with this gesture.
@ -109,7 +104,6 @@ define(
hideBubble(); hideBubble();
// ...and detach listeners // ...and detach listeners
element.off('click', showBubble); element.off('click', showBubble);
scopeOff();
} }
}; };
} }

View File

@ -137,6 +137,11 @@ define(
); );
}); });
// https://github.com/nasa/openmct/issues/948
it("does not try to access scope", function () {
expect(mockElement.scope).not.toHaveBeenCalled();
});
}); });
} }
); );

View File

@ -127,7 +127,16 @@ define([
14400000, 14400000,
28800000, 28800000,
43200000, 43200000,
86400000 86400000,
86400000 * 2,
86400000 * 5,
86400000 * 10,
86400000 * 20,
86400000 * 30,
86400000 * 60,
86400000 * 120,
86400000 * 240,
86400000 * 365
], ],
"width": 200 "width": 200
} }

View File

@ -103,6 +103,13 @@
<!-- TOP PANE GANTT BARS --> <!-- TOP PANE GANTT BARS -->
<div class="split-pane-component l-timeline-pane t-pane-h l-pane-top t-timeline-gantt l-timeline-gantt s-timeline-gantt"> <div class="split-pane-component l-timeline-pane t-pane-h l-pane-top t-timeline-gantt l-timeline-gantt s-timeline-gantt">
<div class="l-hover-btns-holder s-hover-btns-holder t-btns-zoom"> <div class="l-hover-btns-holder s-hover-btns-holder t-btns-zoom">
<a class="t-btn l-btn s-btn"
ng-click="zoomController.fit()"
ng-show="true"
title="Zoom to fit">
<span class="ui-symbol icon zoom-in">I</span>
</a>
<a class="t-btn l-btn s-btn" <a class="t-btn l-btn s-btn"
ng-click="zoomController.zoom(-1)" ng-click="zoomController.zoom(-1)"
ng-show="true" ng-show="true"
@ -121,7 +128,7 @@
<div style="overflow: hidden; position: absolute; left: 0; top: 0; right: 0; height: 30px;" mct-scroll-x="scroll.x"> <div style="overflow: hidden; position: absolute; left: 0; top: 0; right: 0; height: 30px;" mct-scroll-x="scroll.x">
<mct-include key="'timeline-ticks'" <mct-include key="'timeline-ticks'"
parameters="{ parameters="{
fullWidth: zoomController.toPixels(zoomController.duration()), fullWidth: timelineController.width(zoomController),
start: scroll.x, start: scroll.x,
width: scroll.width, width: scroll.width,
step: zoomController.toPixels(zoomController.zoom()), step: zoomController.toPixels(zoomController.zoom()),

View File

@ -32,16 +32,26 @@ define(
var zoomLevels = ZOOM_CONFIGURATION.levels || [1000], var zoomLevels = ZOOM_CONFIGURATION.levels || [1000],
zoomIndex = Math.floor(zoomLevels.length / 2), zoomIndex = Math.floor(zoomLevels.length / 2),
tickWidth = ZOOM_CONFIGURATION.width || 200, tickWidth = ZOOM_CONFIGURATION.width || 200,
bounds = { x: 0, width: tickWidth },
duration = 86400000; // Default duration in view duration = 86400000; // Default duration in view
// Round a duration to a larger value, to ensure space for editing // Round a duration to a larger value, to ensure space for editing
function roundDuration(value) { function roundDuration(value) {
// Ensure there's always an extra day or so // Ensure there's always an extra day or so
var sz = zoomLevels[zoomLevels.length - 1]; var tickCount = bounds.width / tickWidth,
sz = zoomLevels[zoomLevels.length - 1] * tickCount;
value *= 1.25; // Add 25% padding to start value *= 1.25; // Add 25% padding to start
return Math.ceil(value / sz) * sz; return Math.ceil(value / sz) * sz;
} }
function toMillis(pixels) {
return (pixels / tickWidth) * zoomLevels[zoomIndex];
}
function toPixels(millis) {
return tickWidth * millis / zoomLevels[zoomIndex];
}
// Get/set zoom level // Get/set zoom level
function setZoomLevel(level) { function setZoomLevel(level) {
if (!isNaN(level)) { if (!isNaN(level)) {
@ -53,20 +63,27 @@ define(
} }
} }
// Persist current zoom level function initializeZoomFromTimespan(timespan) {
function storeZoom() { var timelineDuration = timespan.getDuration();
var isEditMode = $scope.commit && zoomIndex = 0;
$scope.domainObject && while (toMillis(bounds.width) < timelineDuration &&
$scope.domainObject.hasCapability('editor') && zoomIndex < zoomLevels.length - 1) {
$scope.domainObject.getCapability('editor').inEditContext(); zoomIndex += 1;
if (isEditMode) { }
$scope.configuration = $scope.configuration || {}; bounds.x = toPixels(timespan.getStart());
$scope.configuration.zoomLevel = zoomIndex; }
$scope.commit();
function initializeZoom() {
if ($scope.domainObject) {
$scope.domainObject.useCapability('timespan')
.then(initializeZoomFromTimespan);
} }
} }
$scope.$watch("configuration.zoomLevel", setZoomLevel); $scope.$watch("scroll", function (scroll) {
bounds = scroll;
});
$scope.$watch("domainObject", initializeZoom);
return { return {
/** /**
@ -83,27 +100,29 @@ define(
zoom: function (amount) { zoom: function (amount) {
// Update the zoom level if called with an argument // Update the zoom level if called with an argument
if (arguments.length > 0 && !isNaN(amount)) { if (arguments.length > 0 && !isNaN(amount)) {
var center = this.toMillis(bounds.x + bounds.width / 2);
setZoomLevel(zoomIndex + amount); setZoomLevel(zoomIndex + amount);
storeZoom(zoomIndex); bounds.x = this.toPixels(center) - bounds.width / 2;
} }
return zoomLevels[zoomIndex]; return zoomLevels[zoomIndex];
}, },
/**
* Set the zoom level to fit the bounds of the timeline
* being viewed.
*/
fit: initializeZoom,
/** /**
* Get the width, in pixels, of a specific time duration at * Get the width, in pixels, of a specific time duration at
* the current zoom level. * the current zoom level.
* @returns {number} the number of pixels * @returns {number} the number of pixels
*/ */
toPixels: function (millis) { toPixels: toPixels,
return tickWidth * millis / zoomLevels[zoomIndex];
},
/** /**
* Get the time duration, in milliseconds, occupied by the * Get the time duration, in milliseconds, occupied by the
* width (specified in pixels) at the current zoom level. * width (specified in pixels) at the current zoom level.
* @returns {number} the number of pixels * @returns {number} the number of pixels
*/ */
toMillis: function (pixels) { toMillis: toMillis,
return (pixels / tickWidth) * zoomLevels[zoomIndex];
},
/** /**
* Get or set the current displayed duration. If used as a * Get or set the current displayed duration. If used as a
* setter, this will typically be rounded up to ensure extra * setter, this will typically be rounded up to ensure extra

View File

@ -32,11 +32,7 @@ define(
beforeEach(function () { beforeEach(function () {
testConfiguration = { testConfiguration = {
levels: [ levels: [1000, 2000, 3500],
1000,
2000,
3500
],
width: 12321 width: 12321
}; };
mockScope = jasmine.createSpyObj("$scope", ['$watch']); mockScope = jasmine.createSpyObj("$scope", ['$watch']);
@ -74,32 +70,61 @@ define(
expect(controller.zoom()).toEqual(3500); expect(controller.zoom()).toEqual(3500);
}); });
it("does not normally persist zoom changes", function () { it("observes scroll bounds", function () {
controller.zoom(1); expect(mockScope.$watch)
expect(mockScope.commit).not.toHaveBeenCalled(); .toHaveBeenCalledWith("scroll", jasmine.any(Function));
}); });
it("persists zoom changes in Edit mode", function () { describe("when watches have fired", function () {
mockScope.domainObject = jasmine.createSpyObj( var mockDomainObject,
'domainObject', mockPromise,
['hasCapability', 'getCapability'] mockTimespan,
); testStart,
mockScope.domainObject.hasCapability.andCallFake(function (c) { testEnd;
return c === 'editor';
beforeEach(function () {
testStart = 3000;
testEnd = 5500;
mockDomainObject = jasmine.createSpyObj('domainObject', [
'getId',
'getModel',
'getCapability',
'useCapability'
]);
mockPromise = jasmine.createSpyObj('promise', ['then']);
mockTimespan = jasmine.createSpyObj('timespan', [
'getStart',
'getEnd',
'getDuration'
]);
mockDomainObject.useCapability.andCallFake(function (c) {
return c === 'timespan' && mockPromise;
});
mockPromise.then.andCallFake(function (callback) {
callback(mockTimespan);
});
mockTimespan.getStart.andReturn(testStart);
mockTimespan.getEnd.andReturn(testEnd);
mockTimespan.getDuration.andReturn(testEnd - testStart);
mockScope.scroll = { x: 0, width: 20000 };
mockScope.domainObject = mockDomainObject;
mockScope.$watch.calls.forEach(function (call) {
call.args[1](mockScope[call.args[0]]);
});
}); });
mockScope.domainObject.getCapability.andCallFake(function (c) {
if (c === 'editor') { it("zooms to fit the timeline", function () {
return { var x1 = mockScope.scroll.x,
inEditContext: function () { x2 = mockScope.scroll.x + mockScope.scroll.width;
return true; expect(Math.round(controller.toMillis(x1)))
} .toEqual(testStart);
}; expect(Math.round(controller.toMillis(x2)))
} .toBeGreaterThan(testEnd);
}); });
controller.zoom(1);
expect(mockScope.commit).toHaveBeenCalled();
expect(mockScope.configuration.zoomLevel)
.toEqual(jasmine.any(Number));
}); });
}); });