- added persistent map configuration for ("snap to grid", "magnetizing"), closed #289

- fixed "snap to grid" bug with "locked" systems
This commit is contained in:
Exodus4D
2016-08-21 22:09:16 +02:00
parent 7a8c3b7f9c
commit 58a4c03c1f
16 changed files with 448 additions and 276 deletions

View File

@@ -5,15 +5,12 @@
define([
'jquery',
'app/map/util',
'farahey'
], function($) {
], function($, MapUtil) {
'use strict';
var config = {
systemClass: 'pf-system' // class for all systems
};
/**
* Cached current "Magnetizer" object
* @type {Magnetizer}
@@ -26,8 +23,7 @@ define([
*/
$.fn.initMagnetizer = function(){
var mapContainer = this;
var systemsOnMap = mapContainer.find('.' + config.systemClass);
var systems = mapContainer.getSystems();
/**
* helper function
@@ -51,13 +47,12 @@ define([
/**
* helper function
* set new syste offset
* set new system offset
* @param system
* @param o
* @private
*/
var _setOffset = function(system, o) {
var markAsUpdated = false;
// new position must be within parent container
@@ -91,14 +86,28 @@ define([
* @private
*/
var _dragFilter = function(id) {
return !$('#' + id).is('.jsPlumb_dragged, .pf-system-locked');
};
return !$('#' + id).hasClass('jsPlumb_dragged');
var gridConstrain = function(gridX, gridY) {
return function(id, current, delta) {
if( mapContainer.hasClass(MapUtil.config.mapGridClass) ){
// active grid
return {
left:(gridX * Math.floor( (current[0] + delta.left) / gridX )) - current[0],
top:(gridY * Math.floor( (current[1] + delta.top) / gridY )) - current[1]
};
}else{
// no grid
return delta;
}
};
};
// main init for "magnetize" feature ------------------------------------------------------
m8 = new Magnetizer({
container: mapContainer,
getContainerPosition:function(c) {
getContainerPosition: function(c) {
return c.offset();
},
getPosition:_offset,
@@ -109,11 +118,11 @@ define([
return $(system).attr('id');
},
setPosition:_setOffset,
elements: systemsOnMap,
filter:_dragFilter,
padding:[8, 8]
elements: systems,
filter: _dragFilter,
padding: [6, 6],
constrain: gridConstrain(MapUtil.config.mapSnapToGridDimension, MapUtil.config.mapSnapToGridDimension)
});
};
$.fn.destroyMagnetizer = function(){
@@ -129,8 +138,6 @@ define([
* @param e
*/
var executeAtEvent = function(map, e){
// check if magnetizer is active
if(m8 !== null && e ){
m8.executeAtEvent(e);
map.repaintEverything();
@@ -149,8 +156,25 @@ define([
}
};
/**
* set/update elements for "magnetization"
* -> (e.g. new systems was added)
* @param map
*/
var setElements = function(map){
if(m8 !== null){
var mapContainer = $(map.getContainer());
var systems = mapContainer.getSystems();
m8.setElements(systems);
// re-arrange systems
executeAtCenter(map);
}
};
return {
executeAtCenter: executeAtCenter,
executeAtEvent: executeAtEvent
executeAtEvent: executeAtEvent,
setElements: setElements
};
});

View File

@@ -27,13 +27,10 @@ define([
y: 0
},
mapSnapToGridDimension: 20, // px for grid snapping (grid YxY)
mapSnapToGrid: false, // "Snap to Grid" feature for drag&drop systems on map (optional)
mapMagnetizer: false, // "Magnetizer" feature for drag&drop systems on map (optional)
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
mapClass: 'pf-map', // class for all maps
mapGridClass: 'pf-grid-small', // class for map grid snapping
mapIdPrefix: 'pf-map-', // id prefix for all maps
systemIdPrefix: 'pf-system-', // id prefix for a system
systemClass: 'pf-system', // class for all systems
@@ -790,15 +787,10 @@ define([
});
// init/update map "magnetization" feature if new systems where added
if(
config.mapMagnetizer === true &&
newSystems > 0
){
mapContainer.initMagnetizer();
// update map "magnetization" when new systems where added
if(newSystems > 0){
MagnetizerWrapper.setElements(mapConfig.map);
}
}
return mapContainer;
@@ -1095,7 +1087,6 @@ define([
* @returns new connection
*/
var drawConnection = function(map, connectionData){
var mapContainer = $( map.getContainer() );
var mapId = mapContainer.data('id');
@@ -1123,7 +1114,6 @@ define([
*/
});
// check if connection is valid (e.g. source/target exist
if( connection instanceof jsPlumb.Connection ){
@@ -1136,14 +1126,14 @@ define([
eolUpdated: connectionData.eolUpdated
});
// add connection types -----------------------------------------------------
// add connection types -------------------------------------------------------------------------
if(connectionData.type){
for(var i = 0; i < connectionData.type.length; i++){
connection.addType(connectionData.type[i]);
}
}
// add connection scope -----------------------------------------------------
// add connection scope -------------------------------------------------------------------------
// connection have the default map Scope scope
var scope = map.Defaults.Scope;
if(connectionData.scope){
@@ -1507,10 +1497,8 @@ define([
* @param system
*/
var setSystemObserver = function(map, system){
system = $(system);
// get map container
var mapContainer = $( map.getContainer() );
var systemHeadExpand = $( system.find('.' + config.systemHeadExpandClass) );
@@ -1523,10 +1511,10 @@ define([
map.draggable(system, {
containment: 'parent',
constrain: true,
//scroll: true, // not working because of customized scrollbar
filter: '.' + config.systemHeadNameClass, // disable drag on "system name"
snapThreshold: config.mapSnapToGridDimension, // distance for grid snapping "magnet" effect (optional)
start: function(params, a, b){
//scroll: true, // not working because of customized scrollbar
filter: '.' + config.systemHeadNameClass, // disable drag on "system name"
snapThreshold: MapUtil.config.mapSnapToGridDimension, // distance for grid snapping "magnet" effect (optional)
start: function(params){
var dragSystem = $(params.el);
mapOverlayTimer = dragSystem.getMapOverlay('timer');
@@ -1534,9 +1522,9 @@ define([
// start map update timer
mapOverlayTimer.startMapUpdateCounter();
// check if grid-snap is enable
if(config.mapSnapToGrid){
params.drag.params.grid = [config.mapSnapToGridDimension, config.mapSnapToGridDimension];
// check if grid-snap is enable -> this enables napping for !CURRENT! Element
if( mapContainer.hasClass(MapUtil.config.mapGridClass) ){
params.drag.params.grid = [MapUtil.config.mapSnapToGridDimension, MapUtil.config.mapSnapToGridDimension];
}else{
delete( params.drag.params.grid );
}
@@ -2163,44 +2151,78 @@ define([
// catch events =========================================================
// toggle global map option (e.g. "grid snap", "magnetization"
$(mapContainer).on('pf:menuMapOption', function(e, data){
// toggle global map option (e.g. "grid snap", "magnetization")
$(mapContainer).on('pf:menuMapOption', function(e, mapOption){
var mapElement = $(this);
var currentMapElement = $(this);
// get map menu config options
var data = MapUtil.mapOptions[mapOption.option];
// toggle map option
config[data.option] = !config[data.option];
var promiseStore = MapUtil.getLocaleData('map', mapElement.data('id') );
promiseStore.then(function(dataStore) {
var notificationText = 'disabled';
var button = $('#' + this.data.buttonId);
var dataExists = false;
// toggle map class (e.g. for grid)
if(data.class){
currentMapElement.toggleClass( config[data.class] );
}
// toggle button class
$(data.button).toggleClass('active');
var notificationText = 'disabled';
if( config[data.option] ){
// call optional jQuery extension on mapElement
if(data.onEnable){
$.fn[ data.onEnable ].apply( currentMapElement );
if(
dataStore &&
dataStore[this.mapOption.option]
){
dataExists = true;
}
// show map overlay info icon
notificationText = 'enabled';
currentMapElement.getMapOverlay('info').updateOverlayIcon(data.option, 'show');
}else{
// call optional jQuery extension on mapElement
if(data.onDisable){
$.fn[ data.onDisable ].apply( currentMapElement );
if(dataExists === mapOption.toggle){
// toggle button class
button.removeClass('active');
// toggle map class (e.g. for grid)
if(this.data.class){
this.mapElement.removeClass( MapUtil.config[this.data.class] );
}
// call optional jQuery extension on mapElement
if(this.data.onDisable){
$.fn[ this.data.onDisable ].apply( this.mapElement );
}
// show map overlay info icon
this.mapElement.getMapOverlay('info').updateOverlayIcon(this.mapOption.option, 'hide');
// delete map option
MapUtil.deleteLocalData('map', this.mapElement.data('id'), this.mapOption.option );
}else{
// toggle button class
button.addClass('active');
// toggle map class (e.g. for grid)
if(this.data.class){
this.mapElement.addClass( MapUtil.config[this.data.class] );
}
// call optional jQuery extension on mapElement
if(this.data.onEnable){
$.fn[ this.data.onEnable ].apply( this.mapElement );
}
// hide map overlay info icon
this.mapElement.getMapOverlay('info').updateOverlayIcon(this.mapOption.option, 'show');
// store map option
MapUtil.storeLocalData('map', this.mapElement.data('id'), this.mapOption.option, 1 );
notificationText = 'enabled';
}
// hide map overlay info icon
currentMapElement.getMapOverlay('info').updateOverlayIcon(data.option, 'hide');
}
Util.showNotify({title: data.description, text: notificationText, type: 'info'});
if(mapOption.toggle){
Util.showNotify({title: this.data.description, text: notificationText, type: 'info'});
}
}.bind({
mapOption: mapOption,
data: data,
mapElement: mapElement
}));
});
// delete system event
@@ -2223,8 +2245,6 @@ define([
system.showSystemInfo(map);
}
});
};
/**
@@ -2476,7 +2496,7 @@ define([
var mapContainer = $(map.getContainer());
// format system status for form select ------------------------------------------------------------------------
// format system status for form select -------------------------------------------------------------
var systemStatus = {};
$.each(Init.systemStatus, function(status, statusData){
systemStatus[statusData.id] = statusData.label;
@@ -2492,7 +2512,7 @@ define([
var defaultSystemStatus = Init.systemStatus[ tempKeys[0] ].id;
// get current map data -> disable systems that are already on it ----------------------------------------------
// get current map data -> disable systems that are already on it -----------------------------------
var mapData = mapContainer.getMapDataFromClient({forceData: true});
var mapSystems = mapData.data.systems;
var mapSystemIds = [];
@@ -2500,13 +2520,13 @@ define([
mapSystemIds.push( mapSystems[i].systemId );
}
// dialog data -------------------------------------------------------------------------------------------------
// dialog data --------------------------------------------------------------------------------------
var data = {
id: config.systemDialogId,
selectClass: config.systemDialogSelectClass
};
// set current position as "default" system to add -------------------------------------------------------------
// set current position as "default" system to add --------------------------------------------------
var currentCharacterLog = Util.getCurrentCharacterLog();
if(
@@ -2518,7 +2538,6 @@ define([
data.currentSystem = currentCharacterLog.system;
}
requirejs(['text!templates/dialog/system.html', 'mustache'], function(template, Mustache) {
var content = Mustache.render(template, data);
@@ -2553,7 +2572,7 @@ define([
mapContainer.getMapOverlay('timer').startMapUpdateCounter();
// calculate new system position -----------------------------------------------
// calculate new system position ------------------------------------------------
var newPosition = {
x: 0,
y: 0
@@ -2578,7 +2597,7 @@ define([
systemDialogData.position = newPosition;
// -----------------------------------------------------------------------------
// ------------------------------------------------------------------------------
var requestData = {
systemData: systemDialogData,
@@ -2632,7 +2651,6 @@ define([
* @param callback
*/
var saveSystem = function(map, requestData, sourceSystem, callback){
$.ajax({
type: 'POST',
url: Init.path.saveSystem,
@@ -2649,14 +2667,8 @@ define([
Util.showNotify({title: 'New system', text: newSystemData.name, type: 'success'});
// re-init "magnetizer" with new added system
if(config.mapMagnetizer === true){
var mapContainer = this.map.getContainer();
$(mapContainer).initMagnetizer();
// re/arrange systems (prevent overlapping)
MagnetizerWrapper.executeAtCenter(this.map);
}
// re/arrange systems (prevent overlapping)
MagnetizerWrapper.setElements(this.map);
if(callback){
callback();
@@ -2666,7 +2678,6 @@ define([
Util.showNotify({title: jqXHR.status + ': saveSystem', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
});
};
/**
@@ -2762,7 +2773,7 @@ define([
}
}
// the current user can only be in a single system -------------------------------------------------------
// the current user can only be in a single system ------------------------------------------
if( !currentUserOnMap){
if(
@@ -2814,7 +2825,7 @@ define([
options.forceData === true
){
// map config -----------------------------------------------------------
// map config -----------------------------------------------------------------------------------
mapData.config = {
id: parseInt( mapElement.data('id') ),
name: mapElement.data('name'),
@@ -2829,10 +2840,10 @@ define([
updated: parseInt( mapElement.data('updated') ),
};
// map data -------------------------------------------------------------
// map data -------------------------------------------------------------------------------------
var data = {};
// systems data ---------------------------------------------------------
// systems data ---------------------------------------------------------------------------------
var systemsData = [];
var systems = mapElement.find('.' + config.systemClass);
@@ -2856,7 +2867,7 @@ define([
data.systems = systemsData;
// connections ----------------------------------------------------------
// connections ----------------------------------------------------------------------------------
var connections = map.getAllConnections();
var connectionsFormatted = [];
@@ -2939,7 +2950,7 @@ define([
};
systemData.userCount = (system.data('userCount') ? parseInt( system.data('userCount') ) : 0);
// position -----------------------------------------------------------------
// position -----------------------------------------------------------------------------------------
var positionData = {};
var currentX = system.css('left');
var currentY = system.css('top');
@@ -3025,7 +3036,7 @@ define([
LogEnabled: true
});
// register all available connection types ------------------------------
// register all available connection types ------------------------------------------------------
newJsPlumbInstance.registerConnectionTypes(globalMapConfig.connectionTypes);
// event after a new connection is established --------------------------
@@ -3034,12 +3045,12 @@ define([
setConnectionObserver(newJsPlumbInstance, info.connection);
});
// event after connection moved -----------------------------------------
// event after connection moved -----------------------------------------------------------------
newJsPlumbInstance.bind('connectionMoved', function(info, e) {
});
// event after DragStop a connection or new connection ------------------
// event after DragStop a connection or new connection ------------------------------------------
newJsPlumbInstance.bind('beforeDrop', function(info) {
var connection = info.connection;
@@ -3076,7 +3087,7 @@ define([
return true;
});
// event before Detach connection ---------------------------------------
// event before Detach connection ---------------------------------------------------------------
newJsPlumbInstance.bind('beforeDetach', function(info) {
return true;
});
@@ -3150,7 +3161,7 @@ define([
var mapWrapper = mapContainer.parents('.' + config.mapWrapperClass);
// auto scroll map to previous position
// auto scroll map to previous position -----------------------------------------------------
var promiseStore = MapUtil.getLocaleData('map', mapContainer.data('id') );
promiseStore.then(function(data) {
// This code runs once the value has been loaded
@@ -3163,9 +3174,17 @@ define([
}
});
if( config.mapMagnetizer === true ){
mapContainer.initMagnetizer();
}
// init magnetizer --------------------------------------------------------------------------
mapContainer.triggerMenuEvent('MapOption', {
option: 'mapMagnetizer',
toggle: false
});
// init grid snap ---------------------------------------------------------------------------
mapContainer.triggerMenuEvent('MapOption', {
option: 'mapSnapToGrid',
toggle: false
});
return false;
}
@@ -3210,7 +3229,7 @@ define([
}
});
// ---------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
// add map overlays after scrollbar is initialized
// because of its absolute position
scrollableElement.initMapOverlays();

View File

@@ -314,18 +314,25 @@ define([
iconElement.addClass('active');
}
// display animation for icon
iconElement.velocity({
opacity: [0.8, 0],
scale: [1, 0],
width: ['26px', 0],
marginLeft: ['3px', 0]
},{
duration: 240,
easing: 'easeInOutQuad'
});
// check if icon is not already visible
// -> prevents unnecessary "show" animation
if( !iconElement.data('visible') ){
// display animation for icon
iconElement.velocity({
opacity: [0.8, 0],
scale: [1, 0],
width: ['26px', 0],
marginLeft: ['3px', 0]
},{
duration: 240,
easing: 'easeInOutQuad'
});
iconElement.data('visible', true);
}
}else if(viewType === 'hide'){
iconElement.removeClass('active').velocity('reverse');
iconElement.data('visible', false);
// check if there is any visible icon remaining
var visibleIcons = mapOverlayInfo.find('i:visible');

View File

@@ -10,10 +10,30 @@ define([
'use strict';
var config = {
mapSnapToGridDimension: 20, // px for grid snapping (grid YxY)
// local storage
characterLocalStoragePrefix: 'character_', // prefix for character data local storage key
mapLocalStoragePrefix: 'map_', // prefix for map data local storage key
mapTabContentClass: 'pf-map-tab-content' // Tab-Content element (parent element)
mapTabContentClass: 'pf-map-tab-content', // Tab-Content element (parent element)
systemClass: 'pf-system', // class for all systems
mapGridClass: 'pf-grid-small' // class for map grid snapping
};
// map menu options
var mapOptions = {
mapMagnetizer: {
buttonId: Util.config.menuButtonMagnetizerId,
description: 'Magnetizer',
onEnable: 'initMagnetizer', // jQuery extension function
onDisable: 'destroyMagnetizer' // jQuery extension function
},
mapSnapToGrid : {
buttonId: Util.config.menuButtonGridId,
description: 'Grid snapping',
class: 'mapGridClass'
}
};
/**
@@ -163,6 +183,15 @@ define([
return effectInfo;
};
/**
* get system elements on a map
* @returns {*|jQuery}
*/
$.fn.getSystems = function(){
return this.find('.' + config.systemClass);
};
/**
* search connections by systems
* @param {Object} map - jsPlumb
@@ -543,6 +572,8 @@ define([
};
return {
config: config,
mapOptions: mapOptions,
getMapTypes: getMapTypes,
getMapScopes: getMapScopes,
getScopeInfoForMap: getScopeInfoForMap,

View File

@@ -73,7 +73,6 @@ define([
/**
* set Tab Observer, events are triggered within map.js
* @param mapContentModule
*/
$.fn.setTabContentObserver = function(){
return this.each(function(){
@@ -91,6 +90,7 @@ define([
/**
* clear all system info modules and remove them
* @param tabContentElement
* @param callback
*/
var removeSystemModules = function(tabContentElement, callback){
tabContentElement.find('.' + config.moduleClass).velocity('transition.slideDownOut', {

View File

@@ -60,7 +60,6 @@ define([
// menu
menuHeadMenuLogoClass: 'pf-head-menu-logo', // class for main menu logo
menuButtonFullScreenId: 'pf-menu-button-fullscreen', // id for menu button "full screen"
// helper element
dynamicElementWrapperId: 'pf-dialog-wrapper'
@@ -103,11 +102,8 @@ define([
)
);
// load header
$('.' + config.pageClass).loadHeader();
// load footer
$('.' + config.pageClass).loadFooter();
// load header / footer
$('.' + config.pageClass).loadHeader().loadFooter();
// load left menu
$('.' + config.pageSlidebarLeftClass).loadLeftMenu();
@@ -172,7 +168,7 @@ define([
).append(
$('<a>', {
class: 'list-group-item hide', // trigger by js
id: config.menuButtonFullScreenId,
id: Util.config.menuButtonFullScreenId,
href: '#'
}).html('&nbsp;&nbsp;Full screen').prepend(
$('<i>',{
@@ -228,7 +224,7 @@ define([
requirejs(['fullScreen'], function() {
if($.fullscreen.isNativelySupported() === true){
$('#' + config.menuButtonFullScreenId).removeClass('hide');
$('#' + Util.config.menuButtonFullScreenId).removeClass('hide');
}
});
};
@@ -265,6 +261,7 @@ define([
).append(
$('<a>', {
class: 'list-group-item',
id: Util.config.menuButtonGridId,
href: '#'
}).html('&nbsp;&nbsp;&nbsp;Grid snapping').prepend(
$('<i>',{
@@ -273,14 +270,13 @@ define([
).on('click', function(){
Util.getMapModule().getActiveMap().triggerMenuEvent('MapOption', {
option: 'mapSnapToGrid',
button: this,
description: 'Grid snapping',
class: 'mapGridClass'
toggle: true
});
})
).append(
$('<a>', {
class: 'list-group-item',
id: Util.config.menuButtonMagnetizerId,
href: '#'
}).html('&nbsp;&nbsp;&nbsp;Magnetizing').prepend(
$('<i>',{
@@ -289,10 +285,7 @@ define([
).on('click', function(){
Util.getMapModule().getActiveMap().triggerMenuEvent('MapOption', {
option: 'mapMagnetizer',
button: this,
description: 'Magnetizer',
onEnable: 'initMagnetizer', // jQuery extension function
onDisable: 'destroyMagnetizer' // jQuery extension function
toggle: true
});
})
).append(
@@ -332,8 +325,12 @@ define([
);
};
/**
* trigger menu event
* @param event
* @param data
*/
$.fn.triggerMenuEvent = function(event, data){
if(data === undefined){
data = {};
}
@@ -445,6 +442,7 @@ define([
}
});
return this;
};
/**
@@ -470,6 +468,8 @@ define([
//show credits info dialog
$.fn.showCreditsDialog();
});
return this;
};
/**
@@ -480,7 +480,7 @@ define([
// on "full-screen" change event
$(document).on('fscreenchange', function(e, state, elem){
var menuButton = $('#' + config.menuButtonFullScreenId);
var menuButton = $('#' + Util.config.menuButtonFullScreenId);
if(state === true){
// full screen active
@@ -627,7 +627,7 @@ define([
content: {
icon: 'fa-bolt',
class: 'txt-color-danger',
title: 'Shutdown',
title: 'Application error',
headline: 'Logged out',
text: [
data.reason

View File

@@ -34,6 +34,11 @@ define([
// head
headMapTrackingId: 'pf-head-map-tracking', // id for "map tracking" toggle (checkbox)
// menu
menuButtonFullScreenId: 'pf-menu-button-fullscreen', // id for menu button "fullscreen"
menuButtonMagnetizerId: 'pf-menu-button-magnetizer', // id for menu button "magnetizer"
menuButtonGridId: 'pf-menu-button-grid', // id for menu button "grid snap"
settingsMessageVelocityOptions: {
duration: 180

File diff suppressed because one or more lines are too long

View File

@@ -5,15 +5,12 @@
define([
'jquery',
'app/map/util',
'farahey'
], function($) {
], function($, MapUtil) {
'use strict';
var config = {
systemClass: 'pf-system' // class for all systems
};
/**
* Cached current "Magnetizer" object
* @type {Magnetizer}
@@ -26,8 +23,7 @@ define([
*/
$.fn.initMagnetizer = function(){
var mapContainer = this;
var systemsOnMap = mapContainer.find('.' + config.systemClass);
var systems = mapContainer.getSystems();
/**
* helper function
@@ -51,13 +47,12 @@ define([
/**
* helper function
* set new syste offset
* set new system offset
* @param system
* @param o
* @private
*/
var _setOffset = function(system, o) {
var markAsUpdated = false;
// new position must be within parent container
@@ -91,14 +86,28 @@ define([
* @private
*/
var _dragFilter = function(id) {
return !$('#' + id).is('.jsPlumb_dragged, .pf-system-locked');
};
return !$('#' + id).hasClass('jsPlumb_dragged');
var gridConstrain = function(gridX, gridY) {
return function(id, current, delta) {
if( mapContainer.hasClass(MapUtil.config.mapGridClass) ){
// active grid
return {
left:(gridX * Math.floor( (current[0] + delta.left) / gridX )) - current[0],
top:(gridY * Math.floor( (current[1] + delta.top) / gridY )) - current[1]
};
}else{
// no grid
return delta;
}
};
};
// main init for "magnetize" feature ------------------------------------------------------
m8 = new Magnetizer({
container: mapContainer,
getContainerPosition:function(c) {
getContainerPosition: function(c) {
return c.offset();
},
getPosition:_offset,
@@ -109,11 +118,11 @@ define([
return $(system).attr('id');
},
setPosition:_setOffset,
elements: systemsOnMap,
filter:_dragFilter,
padding:[8, 8]
elements: systems,
filter: _dragFilter,
padding: [6, 6],
constrain: gridConstrain(MapUtil.config.mapSnapToGridDimension, MapUtil.config.mapSnapToGridDimension)
});
};
$.fn.destroyMagnetizer = function(){
@@ -129,8 +138,6 @@ define([
* @param e
*/
var executeAtEvent = function(map, e){
// check if magnetizer is active
if(m8 !== null && e ){
m8.executeAtEvent(e);
map.repaintEverything();
@@ -149,8 +156,25 @@ define([
}
};
/**
* set/update elements for "magnetization"
* -> (e.g. new systems was added)
* @param map
*/
var setElements = function(map){
if(m8 !== null){
var mapContainer = $(map.getContainer());
var systems = mapContainer.getSystems();
m8.setElements(systems);
// re-arrange systems
executeAtCenter(map);
}
};
return {
executeAtCenter: executeAtCenter,
executeAtEvent: executeAtEvent
executeAtEvent: executeAtEvent,
setElements: setElements
};
});

View File

@@ -27,13 +27,10 @@ define([
y: 0
},
mapSnapToGridDimension: 20, // px for grid snapping (grid YxY)
mapSnapToGrid: false, // "Snap to Grid" feature for drag&drop systems on map (optional)
mapMagnetizer: false, // "Magnetizer" feature for drag&drop systems on map (optional)
mapWrapperClass: 'pf-map-wrapper', // wrapper div (scrollable)
mapClass: 'pf-map', // class for all maps
mapGridClass: 'pf-grid-small', // class for map grid snapping
mapIdPrefix: 'pf-map-', // id prefix for all maps
systemIdPrefix: 'pf-system-', // id prefix for a system
systemClass: 'pf-system', // class for all systems
@@ -790,15 +787,10 @@ define([
});
// init/update map "magnetization" feature if new systems where added
if(
config.mapMagnetizer === true &&
newSystems > 0
){
mapContainer.initMagnetizer();
// update map "magnetization" when new systems where added
if(newSystems > 0){
MagnetizerWrapper.setElements(mapConfig.map);
}
}
return mapContainer;
@@ -1095,7 +1087,6 @@ define([
* @returns new connection
*/
var drawConnection = function(map, connectionData){
var mapContainer = $( map.getContainer() );
var mapId = mapContainer.data('id');
@@ -1123,7 +1114,6 @@ define([
*/
});
// check if connection is valid (e.g. source/target exist
if( connection instanceof jsPlumb.Connection ){
@@ -1136,14 +1126,14 @@ define([
eolUpdated: connectionData.eolUpdated
});
// add connection types -----------------------------------------------------
// add connection types -------------------------------------------------------------------------
if(connectionData.type){
for(var i = 0; i < connectionData.type.length; i++){
connection.addType(connectionData.type[i]);
}
}
// add connection scope -----------------------------------------------------
// add connection scope -------------------------------------------------------------------------
// connection have the default map Scope scope
var scope = map.Defaults.Scope;
if(connectionData.scope){
@@ -1507,10 +1497,8 @@ define([
* @param system
*/
var setSystemObserver = function(map, system){
system = $(system);
// get map container
var mapContainer = $( map.getContainer() );
var systemHeadExpand = $( system.find('.' + config.systemHeadExpandClass) );
@@ -1523,10 +1511,10 @@ define([
map.draggable(system, {
containment: 'parent',
constrain: true,
//scroll: true, // not working because of customized scrollbar
filter: '.' + config.systemHeadNameClass, // disable drag on "system name"
snapThreshold: config.mapSnapToGridDimension, // distance for grid snapping "magnet" effect (optional)
start: function(params, a, b){
//scroll: true, // not working because of customized scrollbar
filter: '.' + config.systemHeadNameClass, // disable drag on "system name"
snapThreshold: MapUtil.config.mapSnapToGridDimension, // distance for grid snapping "magnet" effect (optional)
start: function(params){
var dragSystem = $(params.el);
mapOverlayTimer = dragSystem.getMapOverlay('timer');
@@ -1534,9 +1522,9 @@ define([
// start map update timer
mapOverlayTimer.startMapUpdateCounter();
// check if grid-snap is enable
if(config.mapSnapToGrid){
params.drag.params.grid = [config.mapSnapToGridDimension, config.mapSnapToGridDimension];
// check if grid-snap is enable -> this enables napping for !CURRENT! Element
if( mapContainer.hasClass(MapUtil.config.mapGridClass) ){
params.drag.params.grid = [MapUtil.config.mapSnapToGridDimension, MapUtil.config.mapSnapToGridDimension];
}else{
delete( params.drag.params.grid );
}
@@ -2163,44 +2151,78 @@ define([
// catch events =========================================================
// toggle global map option (e.g. "grid snap", "magnetization"
$(mapContainer).on('pf:menuMapOption', function(e, data){
// toggle global map option (e.g. "grid snap", "magnetization")
$(mapContainer).on('pf:menuMapOption', function(e, mapOption){
var mapElement = $(this);
var currentMapElement = $(this);
// get map menu config options
var data = MapUtil.mapOptions[mapOption.option];
// toggle map option
config[data.option] = !config[data.option];
var promiseStore = MapUtil.getLocaleData('map', mapElement.data('id') );
promiseStore.then(function(dataStore) {
var notificationText = 'disabled';
var button = $('#' + this.data.buttonId);
var dataExists = false;
// toggle map class (e.g. for grid)
if(data.class){
currentMapElement.toggleClass( config[data.class] );
}
// toggle button class
$(data.button).toggleClass('active');
var notificationText = 'disabled';
if( config[data.option] ){
// call optional jQuery extension on mapElement
if(data.onEnable){
$.fn[ data.onEnable ].apply( currentMapElement );
if(
dataStore &&
dataStore[this.mapOption.option]
){
dataExists = true;
}
// show map overlay info icon
notificationText = 'enabled';
currentMapElement.getMapOverlay('info').updateOverlayIcon(data.option, 'show');
}else{
// call optional jQuery extension on mapElement
if(data.onDisable){
$.fn[ data.onDisable ].apply( currentMapElement );
if(dataExists === mapOption.toggle){
// toggle button class
button.removeClass('active');
// toggle map class (e.g. for grid)
if(this.data.class){
this.mapElement.removeClass( MapUtil.config[this.data.class] );
}
// call optional jQuery extension on mapElement
if(this.data.onDisable){
$.fn[ this.data.onDisable ].apply( this.mapElement );
}
// show map overlay info icon
this.mapElement.getMapOverlay('info').updateOverlayIcon(this.mapOption.option, 'hide');
// delete map option
MapUtil.deleteLocalData('map', this.mapElement.data('id'), this.mapOption.option );
}else{
// toggle button class
button.addClass('active');
// toggle map class (e.g. for grid)
if(this.data.class){
this.mapElement.addClass( MapUtil.config[this.data.class] );
}
// call optional jQuery extension on mapElement
if(this.data.onEnable){
$.fn[ this.data.onEnable ].apply( this.mapElement );
}
// hide map overlay info icon
this.mapElement.getMapOverlay('info').updateOverlayIcon(this.mapOption.option, 'show');
// store map option
MapUtil.storeLocalData('map', this.mapElement.data('id'), this.mapOption.option, 1 );
notificationText = 'enabled';
}
// hide map overlay info icon
currentMapElement.getMapOverlay('info').updateOverlayIcon(data.option, 'hide');
}
Util.showNotify({title: data.description, text: notificationText, type: 'info'});
if(mapOption.toggle){
Util.showNotify({title: this.data.description, text: notificationText, type: 'info'});
}
}.bind({
mapOption: mapOption,
data: data,
mapElement: mapElement
}));
});
// delete system event
@@ -2223,8 +2245,6 @@ define([
system.showSystemInfo(map);
}
});
};
/**
@@ -2476,7 +2496,7 @@ define([
var mapContainer = $(map.getContainer());
// format system status for form select ------------------------------------------------------------------------
// format system status for form select -------------------------------------------------------------
var systemStatus = {};
$.each(Init.systemStatus, function(status, statusData){
systemStatus[statusData.id] = statusData.label;
@@ -2492,7 +2512,7 @@ define([
var defaultSystemStatus = Init.systemStatus[ tempKeys[0] ].id;
// get current map data -> disable systems that are already on it ----------------------------------------------
// get current map data -> disable systems that are already on it -----------------------------------
var mapData = mapContainer.getMapDataFromClient({forceData: true});
var mapSystems = mapData.data.systems;
var mapSystemIds = [];
@@ -2500,13 +2520,13 @@ define([
mapSystemIds.push( mapSystems[i].systemId );
}
// dialog data -------------------------------------------------------------------------------------------------
// dialog data --------------------------------------------------------------------------------------
var data = {
id: config.systemDialogId,
selectClass: config.systemDialogSelectClass
};
// set current position as "default" system to add -------------------------------------------------------------
// set current position as "default" system to add --------------------------------------------------
var currentCharacterLog = Util.getCurrentCharacterLog();
if(
@@ -2518,7 +2538,6 @@ define([
data.currentSystem = currentCharacterLog.system;
}
requirejs(['text!templates/dialog/system.html', 'mustache'], function(template, Mustache) {
var content = Mustache.render(template, data);
@@ -2553,7 +2572,7 @@ define([
mapContainer.getMapOverlay('timer').startMapUpdateCounter();
// calculate new system position -----------------------------------------------
// calculate new system position ------------------------------------------------
var newPosition = {
x: 0,
y: 0
@@ -2578,7 +2597,7 @@ define([
systemDialogData.position = newPosition;
// -----------------------------------------------------------------------------
// ------------------------------------------------------------------------------
var requestData = {
systemData: systemDialogData,
@@ -2632,7 +2651,6 @@ define([
* @param callback
*/
var saveSystem = function(map, requestData, sourceSystem, callback){
$.ajax({
type: 'POST',
url: Init.path.saveSystem,
@@ -2649,14 +2667,8 @@ define([
Util.showNotify({title: 'New system', text: newSystemData.name, type: 'success'});
// re-init "magnetizer" with new added system
if(config.mapMagnetizer === true){
var mapContainer = this.map.getContainer();
$(mapContainer).initMagnetizer();
// re/arrange systems (prevent overlapping)
MagnetizerWrapper.executeAtCenter(this.map);
}
// re/arrange systems (prevent overlapping)
MagnetizerWrapper.setElements(this.map);
if(callback){
callback();
@@ -2666,7 +2678,6 @@ define([
Util.showNotify({title: jqXHR.status + ': saveSystem', text: reason, type: 'warning'});
$(document).setProgramStatus('problem');
});
};
/**
@@ -2762,7 +2773,7 @@ define([
}
}
// the current user can only be in a single system -------------------------------------------------------
// the current user can only be in a single system ------------------------------------------
if( !currentUserOnMap){
if(
@@ -2814,7 +2825,7 @@ define([
options.forceData === true
){
// map config -----------------------------------------------------------
// map config -----------------------------------------------------------------------------------
mapData.config = {
id: parseInt( mapElement.data('id') ),
name: mapElement.data('name'),
@@ -2829,10 +2840,10 @@ define([
updated: parseInt( mapElement.data('updated') ),
};
// map data -------------------------------------------------------------
// map data -------------------------------------------------------------------------------------
var data = {};
// systems data ---------------------------------------------------------
// systems data ---------------------------------------------------------------------------------
var systemsData = [];
var systems = mapElement.find('.' + config.systemClass);
@@ -2856,7 +2867,7 @@ define([
data.systems = systemsData;
// connections ----------------------------------------------------------
// connections ----------------------------------------------------------------------------------
var connections = map.getAllConnections();
var connectionsFormatted = [];
@@ -2939,7 +2950,7 @@ define([
};
systemData.userCount = (system.data('userCount') ? parseInt( system.data('userCount') ) : 0);
// position -----------------------------------------------------------------
// position -----------------------------------------------------------------------------------------
var positionData = {};
var currentX = system.css('left');
var currentY = system.css('top');
@@ -3025,7 +3036,7 @@ define([
LogEnabled: true
});
// register all available connection types ------------------------------
// register all available connection types ------------------------------------------------------
newJsPlumbInstance.registerConnectionTypes(globalMapConfig.connectionTypes);
// event after a new connection is established --------------------------
@@ -3034,12 +3045,12 @@ define([
setConnectionObserver(newJsPlumbInstance, info.connection);
});
// event after connection moved -----------------------------------------
// event after connection moved -----------------------------------------------------------------
newJsPlumbInstance.bind('connectionMoved', function(info, e) {
});
// event after DragStop a connection or new connection ------------------
// event after DragStop a connection or new connection ------------------------------------------
newJsPlumbInstance.bind('beforeDrop', function(info) {
var connection = info.connection;
@@ -3076,7 +3087,7 @@ define([
return true;
});
// event before Detach connection ---------------------------------------
// event before Detach connection ---------------------------------------------------------------
newJsPlumbInstance.bind('beforeDetach', function(info) {
return true;
});
@@ -3150,7 +3161,7 @@ define([
var mapWrapper = mapContainer.parents('.' + config.mapWrapperClass);
// auto scroll map to previous position
// auto scroll map to previous position -----------------------------------------------------
var promiseStore = MapUtil.getLocaleData('map', mapContainer.data('id') );
promiseStore.then(function(data) {
// This code runs once the value has been loaded
@@ -3163,9 +3174,17 @@ define([
}
});
if( config.mapMagnetizer === true ){
mapContainer.initMagnetizer();
}
// init magnetizer --------------------------------------------------------------------------
mapContainer.triggerMenuEvent('MapOption', {
option: 'mapMagnetizer',
toggle: false
});
// init grid snap ---------------------------------------------------------------------------
mapContainer.triggerMenuEvent('MapOption', {
option: 'mapSnapToGrid',
toggle: false
});
return false;
}
@@ -3210,7 +3229,7 @@ define([
}
});
// ---------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
// add map overlays after scrollbar is initialized
// because of its absolute position
scrollableElement.initMapOverlays();

View File

@@ -314,18 +314,25 @@ define([
iconElement.addClass('active');
}
// display animation for icon
iconElement.velocity({
opacity: [0.8, 0],
scale: [1, 0],
width: ['26px', 0],
marginLeft: ['3px', 0]
},{
duration: 240,
easing: 'easeInOutQuad'
});
// check if icon is not already visible
// -> prevents unnecessary "show" animation
if( !iconElement.data('visible') ){
// display animation for icon
iconElement.velocity({
opacity: [0.8, 0],
scale: [1, 0],
width: ['26px', 0],
marginLeft: ['3px', 0]
},{
duration: 240,
easing: 'easeInOutQuad'
});
iconElement.data('visible', true);
}
}else if(viewType === 'hide'){
iconElement.removeClass('active').velocity('reverse');
iconElement.data('visible', false);
// check if there is any visible icon remaining
var visibleIcons = mapOverlayInfo.find('i:visible');

View File

@@ -10,10 +10,30 @@ define([
'use strict';
var config = {
mapSnapToGridDimension: 20, // px for grid snapping (grid YxY)
// local storage
characterLocalStoragePrefix: 'character_', // prefix for character data local storage key
mapLocalStoragePrefix: 'map_', // prefix for map data local storage key
mapTabContentClass: 'pf-map-tab-content' // Tab-Content element (parent element)
mapTabContentClass: 'pf-map-tab-content', // Tab-Content element (parent element)
systemClass: 'pf-system', // class for all systems
mapGridClass: 'pf-grid-small' // class for map grid snapping
};
// map menu options
var mapOptions = {
mapMagnetizer: {
buttonId: Util.config.menuButtonMagnetizerId,
description: 'Magnetizer',
onEnable: 'initMagnetizer', // jQuery extension function
onDisable: 'destroyMagnetizer' // jQuery extension function
},
mapSnapToGrid : {
buttonId: Util.config.menuButtonGridId,
description: 'Grid snapping',
class: 'mapGridClass'
}
};
/**
@@ -163,6 +183,15 @@ define([
return effectInfo;
};
/**
* get system elements on a map
* @returns {*|jQuery}
*/
$.fn.getSystems = function(){
return this.find('.' + config.systemClass);
};
/**
* search connections by systems
* @param {Object} map - jsPlumb
@@ -543,6 +572,8 @@ define([
};
return {
config: config,
mapOptions: mapOptions,
getMapTypes: getMapTypes,
getMapScopes: getMapScopes,
getScopeInfoForMap: getScopeInfoForMap,

View File

@@ -73,7 +73,6 @@ define([
/**
* set Tab Observer, events are triggered within map.js
* @param mapContentModule
*/
$.fn.setTabContentObserver = function(){
return this.each(function(){
@@ -91,6 +90,7 @@ define([
/**
* clear all system info modules and remove them
* @param tabContentElement
* @param callback
*/
var removeSystemModules = function(tabContentElement, callback){
tabContentElement.find('.' + config.moduleClass).velocity('transition.slideDownOut', {

View File

@@ -60,7 +60,6 @@ define([
// menu
menuHeadMenuLogoClass: 'pf-head-menu-logo', // class for main menu logo
menuButtonFullScreenId: 'pf-menu-button-fullscreen', // id for menu button "full screen"
// helper element
dynamicElementWrapperId: 'pf-dialog-wrapper'
@@ -103,11 +102,8 @@ define([
)
);
// load header
$('.' + config.pageClass).loadHeader();
// load footer
$('.' + config.pageClass).loadFooter();
// load header / footer
$('.' + config.pageClass).loadHeader().loadFooter();
// load left menu
$('.' + config.pageSlidebarLeftClass).loadLeftMenu();
@@ -172,7 +168,7 @@ define([
).append(
$('<a>', {
class: 'list-group-item hide', // trigger by js
id: config.menuButtonFullScreenId,
id: Util.config.menuButtonFullScreenId,
href: '#'
}).html('&nbsp;&nbsp;Full screen').prepend(
$('<i>',{
@@ -228,7 +224,7 @@ define([
requirejs(['fullScreen'], function() {
if($.fullscreen.isNativelySupported() === true){
$('#' + config.menuButtonFullScreenId).removeClass('hide');
$('#' + Util.config.menuButtonFullScreenId).removeClass('hide');
}
});
};
@@ -265,6 +261,7 @@ define([
).append(
$('<a>', {
class: 'list-group-item',
id: Util.config.menuButtonGridId,
href: '#'
}).html('&nbsp;&nbsp;&nbsp;Grid snapping').prepend(
$('<i>',{
@@ -273,14 +270,13 @@ define([
).on('click', function(){
Util.getMapModule().getActiveMap().triggerMenuEvent('MapOption', {
option: 'mapSnapToGrid',
button: this,
description: 'Grid snapping',
class: 'mapGridClass'
toggle: true
});
})
).append(
$('<a>', {
class: 'list-group-item',
id: Util.config.menuButtonMagnetizerId,
href: '#'
}).html('&nbsp;&nbsp;&nbsp;Magnetizing').prepend(
$('<i>',{
@@ -289,10 +285,7 @@ define([
).on('click', function(){
Util.getMapModule().getActiveMap().triggerMenuEvent('MapOption', {
option: 'mapMagnetizer',
button: this,
description: 'Magnetizer',
onEnable: 'initMagnetizer', // jQuery extension function
onDisable: 'destroyMagnetizer' // jQuery extension function
toggle: true
});
})
).append(
@@ -332,8 +325,12 @@ define([
);
};
/**
* trigger menu event
* @param event
* @param data
*/
$.fn.triggerMenuEvent = function(event, data){
if(data === undefined){
data = {};
}
@@ -445,6 +442,7 @@ define([
}
});
return this;
};
/**
@@ -470,6 +468,8 @@ define([
//show credits info dialog
$.fn.showCreditsDialog();
});
return this;
};
/**
@@ -480,7 +480,7 @@ define([
// on "full-screen" change event
$(document).on('fscreenchange', function(e, state, elem){
var menuButton = $('#' + config.menuButtonFullScreenId);
var menuButton = $('#' + Util.config.menuButtonFullScreenId);
if(state === true){
// full screen active
@@ -627,7 +627,7 @@ define([
content: {
icon: 'fa-bolt',
class: 'txt-color-danger',
title: 'Shutdown',
title: 'Application error',
headline: 'Logged out',
text: [
data.reason

View File

@@ -34,6 +34,11 @@ define([
// head
headMapTrackingId: 'pf-head-map-tracking', // id for "map tracking" toggle (checkbox)
// menu
menuButtonFullScreenId: 'pf-menu-button-fullscreen', // id for menu button "fullscreen"
menuButtonMagnetizerId: 'pf-menu-button-magnetizer', // id for menu button "magnetizer"
menuButtonGridId: 'pf-menu-button-grid', // id for menu button "grid snap"
settingsMessageVelocityOptions: {
duration: 180

View File

@@ -100,7 +100,7 @@ $mapWidth: 2500px ;
}
&.glyphicon{
margin-top: 3px;
margin-top: 1px;
font-size: 24px;
padding-left: 3px;
}