Skip to content
This repository has been archived by the owner on Apr 5, 2018. It is now read-only.

Commit

Permalink
Created control 'ContextMenu' for displaying controls in a panel appe…
Browse files Browse the repository at this point in the history
…aring next to the selected features
  • Loading branch information
Mario Härtwig committed Feb 11, 2015
1 parent 35c6c44 commit 72dd05e
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 3 deletions.
3 changes: 2 additions & 1 deletion Makefile
Expand Up @@ -38,6 +38,7 @@ minified:
--js 'lib/Editor/Control/UndoRedo.js' \
--js 'lib/Editor/Control/CADTools.js' \
--js 'lib/Editor/Control/ParallelDrawing.js' \
--js 'lib/Editor/Control/ContextMenu.js' \
--js 'lib/Editor/Lang/ca.js' \
--js 'lib/Editor/Lang/de.js' \
--js 'lib/Editor/Lang/en.js' \
Expand All @@ -50,4 +51,4 @@ pack_distribution: minified
zip --recurse-paths $(DISTRIBUTION_NAME).zip examples/ lib/ tests/ theme/ documentation.md features.md license.txt Makefile README.md ole.min.js

rm -f $(DISTRIBUTION_NAME).tar.gz
tar -pczf $(DISTRIBUTION_NAME).tar.gz examples/ lib/ tests/ theme/ documentation.md features.md license.txt Makefile README.md ole.min.js
tar -pczf $(DISTRIBUTION_NAME).tar.gz examples/ lib/ tests/ theme/ documentation.md features.md license.txt Makefile README.md ole.min.js
19 changes: 17 additions & 2 deletions lib/Editor.js
Expand Up @@ -81,7 +81,7 @@ OpenLayers.Editor = OpenLayers.Class({
editorControls: ['CleanFeature', 'DeleteFeature', 'DeleteAllFeatures', 'Dialog', 'DrawHole', 'DrawRegular',
'DrawPolygon', 'DrawPath', 'DrawPoint', 'DrawText', 'EditorPanel', 'ImportFeature',
'MergeFeature', 'SnappingSettings', 'SplitFeature', 'CADTools',
'TransformFeature'],
'TransformFeature', 'ContextMenu'],

/**
* Geometry types available for editing
Expand Down Expand Up @@ -427,7 +427,6 @@ OpenLayers.Editor = OpenLayers.Class({
OpenLayers.Util.extend({}, this.UploadFeature)
));
break;

}

// Save instance in editor's controls mapping
Expand Down Expand Up @@ -456,6 +455,22 @@ OpenLayers.Editor = OpenLayers.Class({
* @return {OpenLayers.Editor.Control.EditorPanel} Widget to display editing tools
*/
createEditorPanel: function (controls) {

// remove controls from context menu
if (this.controls['ContextMenu']) {
var ctrls = this.controls['ContextMenu'].contextMenuControls || [];
var i = ctrls.length;
while (i--) {
var pos = controls.indexOf(this.controls[ctrls[i]]);
if (~pos) {
controls.splice(pos, 1);
}
}

controls.splice(controls.indexOf(this.controls['ContextMenu']), 1);
}


var editorPanel = new OpenLayers.Editor.Control.EditorPanel(this);
editorPanel.addControls(controls);
return editorPanel;
Expand Down
145 changes: 145 additions & 0 deletions lib/Editor/Control/ContextMenu.js
@@ -0,0 +1,145 @@
/**
* @copyright 2015 geOps
* @license https://github.com/geops/ole/blob/master/license.txt
* @link https://github.com/geops/ole
*/

/**
* Class: OpenLayers.Editor.Control.ContextMenu
* The ContextMenu contains editor controls
* and is opened on feature selection
*
* Inherits from:
* - <OpenLayers.Control.Panel>
*
* @constructor
* @param {OpenLayers.Layer} The editor layer
* @param {Object=} options
*/
OpenLayers.Editor.Control.ContextMenu = OpenLayers.Class(OpenLayers.Control.Panel, {

/**
* {Number} Type of the control
*/
type: OpenLayers.Control.TYPE_BUTTON,

/**
* {Number} Distance (in pixel) of the context menu to the bbox
* of the selected features
*/
menuBufferDistance: 10,

/**
* {Array} Contains list of controls appearing on context menu
*/
contextMenuControls: ['CleanFeature', 'DeleteFeature', 'DrawHole',
'MergeFeature', 'SplitFeature', 'TransformFeature'],

/**
* Constructor OpenLayers.Editor.Control.ContextMenu
*
* Parameters:
* @param {OpenLayers.Layer} The editor layer
* @param {Object} options
*/
initialize: function (layer, options) {
layer.events.register('featureselected', this, this.openContextMenu);
layer.events.register('featureunselected', this, this.closeContextMenu);
layer.map.events.register('move', this, this.updatePosition);

OpenLayers.Control.Panel.prototype.initialize.apply(this, [options]);

layer.map.addControl(this);
},

/**
* Move all context menu controls from editor panel
* to this panel
*/
addContextMenuControls: function() {
var controls = [];
for (var i = 0; i < this.contextMenuControls.length; i++) {
var controlName = this.contextMenuControls[i];
var control = this.map.editor.controls[controlName];
if (control) {
controls.push(control);
}
}

this.addControls(controls);
},

/**
* Open the context menu
*/
openContextMenu: function() {
this.div.style.display = '';
this.addContextMenuControls();
this.activate();
this.updatePosition();

for (var i = 0; i < this.controls.length; i++) {
OpenLayers.Element.removeClass(this.controls[i].panel_div,
'oleControlDisabled');
}
},

/**
* Close the context menu
*/
closeContextMenu: function() {
if (!this.map.editor.editLayer.selectedFeatures.length) {
this.div.style.display = 'none';
this.deactivate();
}
},

/**
* Place the context menu on the point on the selected features'
* bounding box with the smallest distance to the map center.
*/
updatePosition: function() {
var selFeatures = this.map.editor.editLayer.selectedFeatures;

if (!selFeatures.length) {
return;
}

var bounds = new OpenLayers.Bounds();
var mapCenter = this.map.getExtent().getCenterLonLat();
mapCenter = new OpenLayers.Geometry.Point(
mapCenter.lon, mapCenter.lat);

for (var i = 0; i < (selFeatures || []).length; i++) {
bounds.extend(selFeatures[i].geometry.getBounds());
}

var dist = bounds.toGeometry().distanceTo(mapCenter,
{'details': true}) || {'x0': bounds.left, 'y0': bounds.top};

var menuPosition = this.map.getPixelFromLonLat(
new OpenLayers.LonLat(dist.x0, dist.y0));

this.div.style.right = 'initial';
this.div.style.left = menuPosition.x + 'px';
this.div.style.top = menuPosition.y + 'px';

if (dist.y0 === bounds.top) {
this.div.style.top = parseInt(this.div.style.top) -
this.menuBufferDistance - this.div.clientHeight + 'px';
} else if (dist.y0 === bounds.bottom) {
this.div.style.top = parseInt(this.div.style.top) +
this.menuBufferDistance + 'px';
}

if (dist.x0 === bounds.left) {
this.div.style.left = parseInt(this.div.style.left) -
this.menuBufferDistance - this.div.clientWidth + 'px';
} else if (dist.x0 === bounds.right) {
this.div.style.left = parseInt(this.div.style.left) +
this.menuBufferDistance + 'px';
}
},

CLASS_NAME: 'oleContextMenu OpenLayers.Editor.Control.EditorPanel'
});
1 change: 1 addition & 0 deletions lib/loader.js
Expand Up @@ -8,6 +8,7 @@
'compat.js',
'Editor.js',
'Editor/Control/CleanFeature.js',
'Editor/Control/ContextMenu.js',
'Editor/Control/DragFeature.js',
'Editor/Control/DeleteFeature.js',
'Editor/Control/DeleteAllFeatures.js',
Expand Down

0 comments on commit 72dd05e

Please sign in to comment.