Skip to content

Commit

Permalink
feat(popup-menu): add menu service
Browse files Browse the repository at this point in the history
Allows to add popup menu to the diagram.

closes #64
  • Loading branch information
ISO50 committed Feb 20, 2015
1 parent 820e4b7 commit 531d11d
Show file tree
Hide file tree
Showing 7 changed files with 427 additions and 5 deletions.
14 changes: 13 additions & 1 deletion assets/diagram-js.css
Expand Up @@ -352,4 +352,16 @@

.djs-bendpoint.djs-dragging .djs-visual {
fill: yellow;
}
}

.popup-menu-entry {
font-size: 20px;
height: 22px;
}

.popup-menu-entry > span {
font-size: 14px;
font-family: Arial, sans-serif;
margin-left: 5px;
vertical-align: 1px;
}
137 changes: 137 additions & 0 deletions lib/features/popup-menu/PopupMenu.js
@@ -0,0 +1,137 @@
'use strict';

var forEach = require('lodash/collection/forEach'),
assign = require('lodash/object/assign'),
domEvent = require('min-dom/lib/event'),
domify = require('min-dom/lib/domify'),
domClasses = require('min-dom/lib/classes'),
domAttr = require('min-dom/lib/attr'),
domRemove = require('min-dom/lib/remove');


function PopupMenu(eventBus, canvas) {

this._eventBus = eventBus;
this._canvas = canvas;
}

PopupMenu.$inject = [ 'eventBus', 'canvas' ];

module.exports = PopupMenu;

PopupMenu.prototype.open = function(position, entries, options) {

var outer = this,
canvas = this._canvas;

var parent = canvas.getContainer();

//------------------------
function PopupMenuInstance() {

var self = this;

this._actions = {};

var _options = {
className: 'popup-menu',
entryClassName: 'entry'
};
assign(_options, options);

// Container setup
var container = this._container = domify('<div>');

assign(container.style, {
position: 'absolute',
left: position.x + 'px',
top: position.y + 'px'
});
domClasses(container).add(_options.className);

// Add entries
forEach(entries, function(entry) {

var entryContainer = domify('<div>');
domClasses(entryContainer).add(entry.className || _options.entryClassName);
domClasses(entryContainer).add('popup-menu-entry');

if (entry.style) {
domAttr(entryContainer, 'style', entry.style);
}

if (entry.action) {
domAttr(entryContainer, 'data-action', entry.action.name);
self._actions[entry.action.name] = entry.action.handler;
}

var title = domify('<span>');
title.textContent = entry.label;
entryContainer.appendChild(title);

container.appendChild(entryContainer);
});

// Event handler
domEvent.bind(container, 'click', function(event) {
self.trigger(event);
});

// apply canvas zoom level
var zoom = canvas.zoom();

container.style.transformOrigin = 'top left';
container.style.transform = 'scale(' + zoom + ')';

// Attach to DOM
parent.appendChild(container);

// Add Handler
this.bindHandlers();
}

PopupMenuInstance.prototype.close = function() {
this.unbindHandlers();
domRemove(this._container);
};

PopupMenuInstance.prototype.bindHandlers = function() {

var self = this,
eventBus = outer._eventBus;

this._closeHandler = function() {
self.close();
};

eventBus.once('contextPad.close', this._closeHandler);
eventBus.once('canvas.viewbox.changed', this._closeHandler);
};

PopupMenuInstance.prototype.unbindHandlers = function() {

var eventBus = outer._eventBus;

eventBus.off('contextPad.close', this._closeHandler);
eventBus.off('canvas.viewbox.changed', this._closeHandler);
};

PopupMenuInstance.prototype.trigger = function(event) {

var element = event.target,
actionName = element.getAttribute('data-action');

var action = this._actions[actionName];

if (action) {
action();
}

// silence other actions
event.preventDefault();
};

var instance = new PopupMenuInstance(position, entries, parent, options);

return instance;
};
6 changes: 6 additions & 0 deletions lib/features/popup-menu/index.js
@@ -0,0 +1,6 @@
'use strict';

module.exports = {
__init__: [ 'popupMenu' ],
popupMenu: [ 'type', require('./PopupMenu') ]
};
7 changes: 4 additions & 3 deletions test/spec/features/context-pad/ContextPadSpec.js
@@ -1,7 +1,8 @@
'use strict';

var TestHelper = require('../../../TestHelper'),
Events = require('../../../util/Events');

var Events = require('../../../util/Events');



/* global bootstrapDiagram, inject */
Expand Down Expand Up @@ -261,4 +262,4 @@ describe('features/context-pad', function() {

});

});
});
1 change: 1 addition & 0 deletions test/spec/features/overlays/OverlaysIntegrationSpec.js
@@ -1,5 +1,6 @@
'use strict';


require('../../../TestHelper');

var Events = require('../../../util/Events');
Expand Down
2 changes: 1 addition & 1 deletion test/spec/features/overlays/OverlaysSpec.js
@@ -1,10 +1,10 @@
'use strict';


require('../../../TestHelper');

/* global bootstrapDiagram, inject */


var forEach = require('lodash/collection/forEach'),
assign = require('lodash/object/assign'),
domify = require('min-dom/lib/domify');
Expand Down

0 comments on commit 531d11d

Please sign in to comment.