Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BaseLayerPicker improvement & Timeline.prototype.destroy() #798

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 30 additions & 2 deletions Source/Widgets/BaseLayerPicker/BaseLayerPicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ define(['./BaseLayerPickerViewModel',
* // and in the body, include: <div id="baseLayerPickerContainer"></div>
*
* //Create the list of available providers we would like the user to select from.
* //This example uses 3, OpenStreetMap, The Black Marble, and a single, non-streaming world image.
* //This example uses 4, OpenStreetMap, The Black Marble, and a single, non-streaming world image,
* //and an array of ImageryLayers with the Bing satellite layer overlayed with the Black Marble layer
* var providerViewModels = [];
* providerViewModels.push(ImageryProviderViewModel.fromConstants({
* name : 'Open\u00adStreet\u00adMap',
Expand Down Expand Up @@ -81,6 +82,33 @@ define(['./BaseLayerPickerViewModel',
* }
* }));
*
* providerViewModels.push(ImageryProviderViewModel.fromConstants({
* name : 'Bing areal with black marble overlay',
* iconUrl : require.toUrl('../Images/ImageryProviders/blackMarble.png'),
* tooltip : 'Bing Areal imagery with the lights of cities and villages trace the outlines of civilization in this global view of the \
Earth at night as seen by NASA/NOAA\'s Suomi NPP satellite.',
* creationFunction : function() {
* var bing = new BingMapsImageryProvider({
* url : 'http://dev.virtualearth.net',
* mapStyle : BingMapsStyle.AERIAL,
* proxy : proxyIfNeeded
* });
*
* var black = new TileMapServiceImageryProvider({
* url : 'http://cesium.agi.com/blackmarble',
* maximumLevel : 8,
* credit : 'Black Marble imagery courtesy NASA Earth Observatory',
* proxy : proxyIfNeeded,
* });
*
* var bingLayer = new ImageryLayer(bing);
* var blackLayer = new ImageryLayer(black);
* blackLayer.alpha = 0.4;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need to ever return an ImageryLayer instead of an ImageryProvider. It looks like you are doing it because you want to set an alpha value, but you can do that now with the ImageryProvider by setting the defaultAlpha property. I just checked and this isn't properly documented, so that's a separate issue which I will write up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see - indeed, I needed to be able to set the alpha value

*
* return [ bingLayer, blackLayer ];
* }
* }));
*
* //Finally, create the actual widget using our view models.
* var layers = centralBody.getImageryLayers();
* var baseLayerPicker = new BaseLayerPicker('baseLayerPickerContainer', layers, providerViewModels);
Expand Down Expand Up @@ -186,4 +214,4 @@ define(['./BaseLayerPickerViewModel',
};

return BaseLayerPicker;
});
});
23 changes: 18 additions & 5 deletions Source/Widgets/BaseLayerPicker/BaseLayerPickerViewModel.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
/*global define*/
define(['../../Core/DeveloperError',
'../../Scene/SceneMode',
'../../Scene/ImageryLayer',
'../../Scene/ImageryProvider',
'../createCommand',
'../../ThirdParty/knockout'
], function(
DeveloperError,
SceneMode,
ImageryLayer,
ImageryProvider,
createCommand,
knockout) {
"use strict";
Expand Down Expand Up @@ -90,12 +94,21 @@ define(['../../Core/DeveloperError',
return selectedViewModel();
},
write : function(value) {
if (imageryLayers.getLength() > 0) {
while (imageryLayers.getLength() > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You changed the code to simply remove all layers when a layer is switched. This is definitely not what we want. Someone may use the widget to allow base layer swapping, but want to manage additional layers on top of that themselves. With this change, that's no longer possible. The work-around would be to have each viewModel always return the same set of imagery providers, this way on remove, we only remove the ones that we originally added. Since we'll use instance comparison, this should work even if the added provider was manually moved around by the user.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough. what I wanted to achieve is to be able to pass multiple layers - what would be your suggestion to be able to achieve this?
the use case is that if someone wants to add a 'set of layers' which overlap each other in semi-transparent ways, he should be able to do that.

imageryLayers.remove(imageryLayers.get(0));
}
var newLayer = value.creationCommand();
if (typeof newLayer !== 'undefined') {
imageryLayers.addImageryProvider(newLayer, 0);
var newLayers = value.creationCommand();
if (typeof newLayers !== 'undefined') {
if (!(newLayers instanceof Array)) {
newLayers = [ newLayers ];
}
for (var i = 0; i < newLayers.length; ++i) {
if (newLayers[i] instanceof ImageryLayer) {
imageryLayers.add(newLayers[i], i);
} else {
imageryLayers.addImageryProvider(newLayers[i], i);
}
}
}
selectedViewModel(value);
dropDownVisible(false);
Expand All @@ -104,4 +117,4 @@ define(['../../Core/DeveloperError',
};

return BaseLayerPickerViewModel;
});
});
91 changes: 62 additions & 29 deletions Source/Widgets/Timeline/Timeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ define([
'../../Core/DeveloperError',
'../../Core/Clock',
'../../Core/ClockRange',
'../../Core/JulianDate'
'../../Core/JulianDate',
'../../Core/destroyObject'
], function (
TimelineTrack,
TimelineHighlightRange,
DeveloperError,
Clock,
ClockRange,
JulianDate) {
JulianDate,
destroyObject) {
"use strict";

var timelineWheelDelta = 1e12;
Expand Down Expand Up @@ -129,37 +131,33 @@ define([

this.zoomTo(clock.startTime, clock.stopTime);

this._timeBarEle.addEventListener('mousedown', function(e) {
widget._handleMouseDown(e);
}, false);
document.addEventListener('mouseup', function(e) {
widget._handleMouseUp(e);
}, false);
document.addEventListener('mousemove', function(e) {
widget._handleMouseMove(e);
}, false);
this._timeBarEle.addEventListener('DOMMouseScroll', function(e) {
widget._handleMouseWheel(e);
}, false); // Mozilla mouse wheel
this._timeBarEle.addEventListener('mousewheel', function(e) {
widget._handleMouseWheel(e);
}, false);
this._timeBarEle.addEventListener('touchstart', function(e) {
widget._handleTouchStart(e);
}, false);
document.addEventListener('touchmove', function(e) {
widget._handleTouchMove(e);
}, false);
document.addEventListener('touchend', function(e) {
widget._handleTouchEnd(e);
}, false);
this._onMouseDown = function(e) { widget._handleMouseDown(e); };
this._timeBarEle.addEventListener('mousedown', this._onMouseDown, false);

this._onMouseMove = function(e) { widget._handleMouseMove(e); };
this._timeBarEle.addEventListener('mousemove', this._onMouseMove, false);

this._onDOMMouseScroll = function(e) { widget._handleMouseWheel(e); };
this._timeBarEle.addEventListener('DOMMouseScroll', this._onDOMMouseScroll, false);

this._onMouseWheel = function(e) { widget._handleMouseWheel(e); };
this._timeBarEle.addEventListener('mousewheel', this._onMouseWheel, false);

this._onTouchStart = function(e) { widget._handleTouchStart(e); };
this._timeBarEle.addEventListener('touchstart', this._onTouchStart, false);

this._onTouchMove = function(e) { widget._handleTouchMove(e); };
this._timeBarEle.addEventListener('touchmove', this._onTouchMove, false);

this._onTouchEnd = function(e) { widget._handleTouchEnd(e); };
this._timeBarEle.addEventListener('touchend', this._onTouchEnd, false);

this.container.oncontextmenu = function() {
return false;
};

window.addEventListener('resize', function() {
widget.handleResize();
}, false);
this._onResize = function() { widget.handleResize(); };
window.addEventListener('resize', this._onResize);

this.addEventListener = function(type, listener, useCapture) {
widget.container.addEventListener(type, listener, useCapture);
Expand Down Expand Up @@ -673,5 +671,40 @@ define([
this._makeTics();
};

/**
* Return if the widget has been destroyed.
* @memberof Timeline
*/
Timeline.prototype.isDestroyed() {
return false;
}

/**
* Destroys the widget. Should be called if permanently
* removing the widget from layout.
* @memberof Timeline
*/
Timeline.prototype.destroy = function() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For completeness, can you add an isDestoyed function as well. It will just always return false. destroyObject will then replace it with a version that returns true.

var container = this.container;

this._timeBarEle.removeEventListener('mousedown', this._onMouseDown, false);
this._timeBarEle.removeEventListener('mousemove', this._onMouseMove, false);
this._timeBarEle.removeEventListener('DOMMouseScroll', this._onDOMMouseScroll, false);
this._timeBarEle.removeEventListener('mousewheel', this._onMouseWheel, false);
this._timeBarEle.removeEventListener('touchstart', this._onTouchStart, false);
this._timeBarEle.removeEventListener('touchmove', this._onTouchMove, false);
this._timeBarEle.removeEventListener('touchend', this._onTouchEnd, false);
window.removeEventListener('resize', this._onResize);

this._clock.onTick.removeEventListener(this.updateFromClock, this);

while (container.firstChild) {
container.removeChild(container.firstChild);
}
container.className = container.className.replace('cesium-timeline-main', '');

return destroyObject(this);
};

return Timeline;
});