diff --git a/addon/components/flexberry-map.js b/addon/components/flexberry-map.js index fea77cb60..ca24e0f38 100644 --- a/addon/components/flexberry-map.js +++ b/addon/components/flexberry-map.js @@ -143,6 +143,8 @@ let FlexberryMapComponent = Ember.Component.extend( */ lat: null, + maptoolOptionsService: Ember.inject.service('maptool-options'), + /** Map center longitude. @@ -503,6 +505,10 @@ let FlexberryMapComponent = Ember.Component.extend( // Store map's container as jQuery object. let $leafletContainer = this.$(); + + // Выключаем стандартный обработчик ПКМ для контейнера карты + $leafletContainer.on('contextmenu', (e) => e.preventDefault()); + this.set('_$leafletContainer', $leafletContainer); let options = this.get('options'); @@ -513,20 +519,107 @@ let FlexberryMapComponent = Ember.Component.extend( if (this.get('mainMap')) { leafletMap.mainMap = true; L.DomEvent.on(leafletMap, 'mousedown mouseup mousein mouseout', (e) => { + // Обработка ПКМ: Включение инструмента идентификации типа "Прямоугольник" + // При mouseDown включение, создание вершины, переключение в draggable-состояние для задания области идентификации + // При mouseUp идентификация, переключение инструмента + if (e.originalEvent.button === 2) { + if (!this.get('maptoolOptionsService.isRightClickToolAvailable')) { + return; + } + + if (e.type === 'mousedown') { + let rightClickAvailiblePrevMapTools = this.get('maptoolOptionsService.rightClickAvailiblePrevMapTools'); + + let prevToolName = leafletMap.flexberryMap.tools.getEnabled().name; + let savePrevEnabledTool = rightClickAvailiblePrevMapTools.some(availiblePrevMapToolName => prevToolName.includes(availiblePrevMapToolName)); + + // Сохраняем предыдущий инструмент из списка "включаемых" инструментов + if (savePrevEnabledTool) { + this.set('prevEnabledTools', { + name: leafletMap.flexberryMap.tools.getEnabled().name, + mapToolProperties: leafletMap.flexberryMap.tools.getEnabled().mapToolProperties + }); + } else { + this.set('prevEnabledTools', null); + } + + // Для переключения некоторых инструментов рисования требуется корректно прервать функциональность (вызвать необходимые обработчики, переключить флаги) + leafletMap.flexberryMap.tools.getEnabled().interrupt(e); + + // ПКМ обработчик карты пока умеет работать только с identify-visible-rectangle + // this.rightClickToolProperties должен содержать перечень слоев для идентификации + // Включаем инструмент идентификации + let rightClickToolName = this.get('maptoolOptionsService.rightClickToolName'); + let rightClickToolProperties = this.get('maptoolOptionsService.rightClickToolProperties'); + let identifyTool = leafletMap.flexberryMap.tools.enable(rightClickToolName, rightClickToolProperties); + let identifyEditTools = Ember.get(identifyTool, '_editTools'); + + // Если _editTools не доступно + if (Ember.isNone(identifyEditTools)) { + console.error('The handler for right click map tool is not defined'); + leafletMap.flexberryMap.tools.enable('drag'); + return; + } + + // Инициируем нажатие ЛКМ для создания стартовой точки и перехода в состояние "перетаскивание" инструмента + let newMouseDownEvent = new MouseEvent('mousedown'); + identifyEditTools.onMousedown({ + latlng: e.latlng, + originalEvent: newMouseDownEvent + }); + } + + if (e.type === 'mouseup') { + let currentMapTool = leafletMap.flexberryMap.tools.getEnabled(); + + if (Ember.get(currentMapTool, 'name') === this.get('maptoolOptionsService.rightClickToolName')) { + let identifyEditTools = Ember.get(currentMapTool, '_editTools'); + + if (!Ember.isNone(identifyEditTools)) { + identifyEditTools.commitDrawing(e); + } + } + + if (!Ember.isNone(this.get('prevEnabledTools'))) { + leafletMap.flexberryMap.tools.enable(this.get('prevEnabledTools.name'), this.get('prevEnabledTools.mapToolProperties')); + } else { + leafletMap.flexberryMap.tools.enable('drag'); + } + + this.set('prevEnabledTools', null); + } + + return; + } + + // Обработка средней клавиши мыши: возможность перетаскивания карты из любого рабочего инструмента + // При mouseDown включение инструмента "рука" + // При mouseUp переключение обратно в рабочий инструмент if (e.originalEvent.button === 1) { if (e.type === 'mousedown') { e.originalEvent.preventDefault(); - let enabledTools = { + + this.set('prevEnabledTools', { name: leafletMap.flexberryMap.tools.getEnabled().name, mapToolProperties: leafletMap.flexberryMap.tools.getEnabled().mapToolProperties - }; - this.set('prevEnabledTools', enabledTools); + }); + leafletMap.flexberryMap.tools.enable('drag'); } else { leafletMap.flexberryMap.tools.enable(this.get('prevEnabledTools.name'), this.get('prevEnabledTools.mapToolProperties')); this.set('prevEnabledTools', null); } - } else if (!Ember.isNone(this.get('prevEnabledTools'))) { + + return; + } + + // Обработка ЛКМ: перезагрузить рабочий инструмент + // Если во время работы инструмента что-то пошло не так (двойной клик, одновременный клик лкм+пкм, выход за границы рабочей области) + if (e.originalEvent.button === 0) { + if (Ember.isNone(this.get('prevEnabledTools'))) { + return; + } + leafletMap.flexberryMap.tools.enable(this.get('prevEnabledTools.name'), this.get('prevEnabledTools.mapToolProperties')); this.set('prevEnabledTools', null); } diff --git a/addon/map-tools/base.js b/addon/map-tools/base.js index 299cd0d19..e965fb17e 100644 --- a/addon/map-tools/base.js +++ b/addon/map-tools/base.js @@ -101,6 +101,16 @@ export default Ember.Object.extend(Ember.Evented, } }, + /** + Safely Interrupts tool functionality. + + @method interrupt + @private + */ + interrupt(e) { + return; + }, + /** Enables tool. diff --git a/addon/map-tools/identify.js b/addon/map-tools/identify.js index 722196a04..7c1b9a2f1 100644 --- a/addon/map-tools/identify.js +++ b/addon/map-tools/identify.js @@ -404,6 +404,15 @@ export default BaseNonclickableMapTool.extend({ if (!Ember.isNone(editTools)) { editTools.off('editable:drawing:mousedown', this._drawingStart, this); editTools.off('editable:drawing:end', this._drawingDidEnd, this); + + if (editTools.drawing()) { + let feature = editTools._drawingEditor ? editTools._drawingEditor.feature : null; + if (feature) { + feature.disableEdit(); + feature.remove(); + } + } + editTools.stopDrawing(); } }, diff --git a/addon/map-tools/measure.js b/addon/map-tools/measure.js index 7ec147bb5..04f1782cb 100644 --- a/addon/map-tools/measure.js +++ b/addon/map-tools/measure.js @@ -95,6 +95,24 @@ export default BaseNonclickableMapTool.extend({ } }, + interrupt(e) { + this._super(...arguments); + let measureTools = this.get('_measureTools'); + + if (Ember.isNone(measureTools)) { + return; + } + + let measureEditTools = Ember.get(measureTools, 'editTools'); + + if (Ember.isNone(measureEditTools)) { + return; + } + + measureEditTools.onMousedown(e); + measureEditTools.onMouseup(e); + }, + /** Handles edit tools 'editable:drawing:end' event. diff --git a/addon/mixins/geom-only-map-tool.js b/addon/mixins/geom-only-map-tool.js index aac41ad45..5ae8403bd 100644 --- a/addon/mixins/geom-only-map-tool.js +++ b/addon/mixins/geom-only-map-tool.js @@ -25,23 +25,5 @@ export default Ember.Mixin.create({ // а работаем в любом случае с workingPolygon leafletMap.fire('flexberry-map:geomChanged', { wkt: workingPolygon.toEWKT(L.CRS.EPSG4326) }); - }, - - _disableDraw() { - let editTools = this.get('_editTools'); - if (!Ember.isNone(editTools)) { - editTools.off('editable:drawing:mousedown', this._drawingStart, this); - editTools.off('editable:drawing:end', this._drawingDidEnd, this); - - if (editTools.drawing()) { - let feature = editTools._drawingEditor ? editTools._drawingEditor.feature : null; - if (feature) { - feature.disableEdit(); - feature.remove(); - } - } - - editTools.stopDrawing(); - } } }); diff --git a/addon/mixins/leaflet-map/map-tools.js b/addon/mixins/leaflet-map/map-tools.js index 62c1fb9b7..6c9ff6749 100644 --- a/addon/mixins/leaflet-map/map-tools.js +++ b/addon/mixins/leaflet-map/map-tools.js @@ -101,10 +101,6 @@ export default Ember.Mixin.create(LeafletMapVisibilityMixin, { mapTool: mapTool }); - if (mapTool === enabledMapTool) { - return enabledMapTool; - } - // Disable enabled map-tool. // It will also trigger 'flexberry-map:tools:disable' event on leaflet map. if (!Ember.isNone(enabledMapTool)) { diff --git a/addon/services/maptool-options.js b/addon/services/maptool-options.js new file mode 100644 index 000000000..e7c10c03a --- /dev/null +++ b/addon/services/maptool-options.js @@ -0,0 +1,37 @@ +import Ember from 'ember'; + +export default Ember.Service.extend({ + /** + Flag: indicates whether tool is performed when right-clicking on map. + + @property isRightClickToolAvailable + @type Bool + @default false + */ + isRightClickToolAvailable: false, + + /** + Map tool that should be enabled when right clicking + + @property rightClickToolName + @type String + @default 'identify-visible-rectangle' + */ + rightClickToolName: 'identify-visible-rectangle', + + /** + Right click map tool options + + @property rightClickToolProperties + @type Object + @default null + */ + rightClickToolProperties: null, + + /** + List of available tools for switching to rightClickTool-mode and saving active state of working tool after + @property rightClickAvailiblePrevMapTools + @type String [] + */ + rightClickAvailiblePrevMapTools: ['drag', 'zoom-in', 'zoom-out', 'identify', 'measure-coordinates', 'measure-distance'] +}); diff --git a/app/services/maptool-options.js b/app/services/maptool-options.js new file mode 100644 index 000000000..bc1fad7ea --- /dev/null +++ b/app/services/maptool-options.js @@ -0,0 +1 @@ +export { default } from 'ember-flexberry-gis/services/maptool-options'; \ No newline at end of file