Commit 7327a128 authored by Thibaut Frain's avatar Thibaut Frain Committed by Jérome Perrin

Enable drag and drop from toolbox to jsplumb graph

parent 613ea05a
...@@ -41,16 +41,18 @@ ...@@ -41,16 +41,18 @@
}) })
.declareMethod("startService", function () { .declareMethod("startService", function () {
var g = this; var g = this,
graph;
return g.getDeclaredGadget("productionline_graph") return g.getDeclaredGadget("productionline_graph")
.push(function (graph) { .push(function (graph_gadget) {
return graph.startService(); graph = graph_gadget;
}) return g.getDeclaredGadget('productionline_toolbox');
.push(function () {
return g.getDeclaredGadget("productionline_toolbox");
}) })
.push(function (toolbox) { .push(function (toolbox) {
return toolbox.startService(); return RSVP.all([
graph.startService(),
toolbox.startService()
]);
}); });
}); });
}(window, rJS, RSVP)); }(window, rJS, RSVP));
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
(function (window, RSVP, FileReader) { (function (window, RSVP, FileReader) {
"use strict"; "use strict";
window.loopEventListener = function (target, type, useCapture, callback) { window.loopEventListener = function (target, type, useCapture, callback,
allowDefault) {
////////////////////////// //////////////////////////
// Infinite event listener (promise is never resolved) // Infinite event listener (promise is never resolved)
// eventListener is removed when promise is cancelled/rejected // eventListener is removed when promise is cancelled/rejected
...@@ -28,7 +29,9 @@ ...@@ -28,7 +29,9 @@
handle_event_callback = function (evt) { handle_event_callback = function (evt) {
evt.stopPropagation(); evt.stopPropagation();
evt.preventDefault(); if (allowDefault !== true) {
evt.preventDefault();
}
cancelResolver(); cancelResolver();
callback_promise = new RSVP.Queue() callback_promise = new RSVP.Queue()
.push(function () { .push(function () {
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<script src="../<%= copy.renderjs.relative_dest %>"></script> <script src="../<%= copy.renderjs.relative_dest %>"></script>
<script src="../<%= curl.jsplumbjs.relative_dest %>"></script> <script src="../<%= curl.jsplumbjs.relative_dest %>"></script>
<script src="../<%= copy.handlebars.relative_dest %>"></script> <script src="../<%= copy.handlebars.relative_dest %>"></script>
<script id="node-template" type="text/x-handlebars-template"> <script id="node-template" type="text/x-handlebars-template">
<div class="window {{class}}" <div class="window {{class}}"
id="{{element_id}}" id="{{element_id}}"
...@@ -20,8 +20,10 @@ ...@@ -20,8 +20,10 @@
<div class="ep"></div> <div class="ep"></div>
</div> </div>
</script> </script>
<script src="../dream/mixin_gadget.js"></script> <script src="../dream/mixin_gadget.js"></script>
<script src="../dream/mixin_promise.js"></script>
<script src="jsplumb.js"></script> <script src="jsplumb.js"></script>
</head> </head>
<body> <body>
......
...@@ -17,16 +17,19 @@ ...@@ -17,16 +17,19 @@
* along with DREAM. If not, see <http://www.gnu.org/licenses/>. * along with DREAM. If not, see <http://www.gnu.org/licenses/>.
* ==========================================================================*/ * ==========================================================================*/
/*global RSVP, rJS, $, jsPlumb, Handlebars, DOMParser, initGadgetMixin*/ /*global RSVP, rJS, $, jsPlumb, Handlebars, initGadgetMixin,
loopEventListener, DOMParser*/
/*jslint unparam: true */ /*jslint unparam: true */
(function (RSVP, rJS, $, jsPlumb, Handlebars, initGadgetMixin) { (function (RSVP, rJS, $, jsPlumb, Handlebars, initGadgetMixin,
loopEventListener, DOMParser) {
"use strict"; "use strict";
/*jslint nomen: true*/ /*jslint nomen: true*/
var gadget_klass = rJS(window), var gadget_klass = rJS(window),
node_template_source = gadget_klass.__template_element node_template_source = gadget_klass.__template_element
.getElementById('node-template').innerHTML, .getElementById('node-template').innerHTML,
node_template = Handlebars.compile(node_template_source); node_template = Handlebars.compile(node_template_source),
domParser = new DOMParser();
function getNodeId(node_container, element_id) { function getNodeId(node_container, element_id) {
var node_id; var node_id;
...@@ -53,13 +56,13 @@ ...@@ -53,13 +56,13 @@
// return (option.short_id || element_type) + n; // return (option.short_id || element_type) + n;
// } // }
// function generateElementId(gadget_element) { function generateElementId(gadget_element) {
// var n = 1; var n = 1;
// while ($(gadget_element).find('#DreamNode_' + n).length > 0) { while ($(gadget_element).find('#DreamNode_' + n).length > 0) {
// n += 1; n += 1;
// } }
// return 'DreamNode_' + n; return 'DreamNode_' + n;
// } }
function onDataChange() { function onDataChange() {
//$.publish("Dream.Gui.onDataChange", g.private.getData()); //$.publish("Dream.Gui.onDataChange", g.private.getData());
...@@ -251,24 +254,24 @@ ...@@ -251,24 +254,24 @@
node_container[element.id] = element_data; node_container[element.id] = element_data;
} }
function redraw(gadget) { // function redraw(gadget) {
var coordinates = gadget.private.preference_container.coordinates || {}, // var coordinates = gadget.props.preference_container.coordinates || {},
absolute_position, // absolute_position,
element; // element;
$.each(coordinates, function (node_id, v) { // $.each(coordinates, function (node_id, v) {
absolute_position = convertToAbsolutePosition( // absolute_position = convertToAbsolutePosition(
gadget, // gadget,
v.left, // v.left,
v.top // v.top
); // );
element = $(gadget.private.element).find( // element = $(gadget.props.element).find(
'#' + getElementId(gadget.private.node_container, node_id) // '#' + getElementId(gadget.props.node_container, node_id)
); // );
element.css('top', absolute_position[1]); // element.css('top', absolute_position[1]);
element.css('left', absolute_position[0]); // element.css('left', absolute_position[0]);
gadget.private.jsplumb_instance.repaint(element); // gadget.props.jsplumb_instance.repaint(element);
}); // });
} // }
// function positionGraph(gadget) { // function positionGraph(gadget) {
// $.ajax( // $.ajax(
...@@ -434,6 +437,9 @@ ...@@ -434,6 +437,9 @@
coordinate coordinate
); );
} }
if (element.element_id === undefined) {
element.element_id = generateElementId(gadget.props.element);
}
/*jslint nomen: true*/ /*jslint nomen: true*/
render_element.append(node_template({ render_element.append(node_template({
"class": element._class.replace('.', '-'), "class": element._class.replace('.', '-'),
...@@ -454,6 +460,60 @@ ...@@ -454,6 +460,60 @@
onDataChange(); onDataChange();
} }
function waitForDragover(gadget) {
return loopEventListener(
gadget.props.main,
'dragover',
false,
function () {return undefined; }
);
}
function waitForDrop(gadget) {
var target = gadget.props.element
.querySelector('#main'),
callback;
function canceller() {
if (callback !== undefined) {
target.removeEventListener('drop', callback, false);
}
}
function nonResolvableTrap(resolve, reject) {
callback = function (evt) {
var element = domParser.parseFromString(
evt.dataTransfer.getData('text/html'),
'text/html'
).querySelector(".tool"),
offset = $(gadget.props.main).offset(),
box_top = evt.clientY - offset.top + "px",
box_left = evt.clientX - offset.left + "px",
element_class = element.id.replace('-', '.'),
relative_position = convertToRelativePosition(
gadget,
box_left,
box_top
);
newElement(gadget, {
coordinate: {
left: relative_position[0],
top: relative_position[1]
},
"_class": element_class,
"name": element_class
});
};
target.addEventListener('drop', callback, false);
}
return new RSVP.Promise(nonResolvableTrap, canceller);
}
initGadgetMixin(gadget_klass);
gadget_klass gadget_klass
.ready(function (g) { .ready(function (g) {
g.props.node_container = {}; g.props.node_container = {};
...@@ -503,5 +563,15 @@ ...@@ -503,5 +563,15 @@
updateElementData(g, key, { updateElementData(g, key, {
data: value.data data: value.data
}); });
}
});
$.each(g.props.data.edges, function (key, value) {
addEdge(g, key, value);
});
return RSVP.all([
waitForDragover(g),
waitForDrop(g)
]);
}); });
}(RSVP, rJS, $, jsPlumb, Handlebars, DOMParser, initGadgetMixin)); }(RSVP, rJS, $, jsPlumb, Handlebars, initGadgetMixin,
loopEventListener, DOMParser));
...@@ -13,13 +13,16 @@ ...@@ -13,13 +13,16 @@
<script id="tool-template" type="text/x-handlebars-template"> <script id="tool-template" type="text/x-handlebars-template">
<div id="{{key}}" <div id="{{key}}"
class="tool {{key}}"> class="tool {{key}}"
draggable="true">
{{name}} {{name}}
<ul/> <ul/>
</div> </div>
</script> </script>
<script src="../dream/mixin_gadget.js"></script> <script src="../dream/mixin_gadget.js"></script>
<script src="../dream/mixin_promise.js"></script>
<script src="toolbox.js"></script> <script src="toolbox.js"></script>
</head> </head>
<body> <body>
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
border-radius: 5px; border-radius: 5px;
text-align: center; text-align: center;
padding-top: 1.3em; padding-top: 1.3em;
cursor: move;
} }
.Dream-Source, .Dream-BatchSource { .Dream-Source, .Dream-BatchSource {
......
/*global window, document, RSVP, rJS, Handlebars*/ /*global window, document, RSVP, rJS, Handlebars, initGadgetMixin*/
(function (window, document, RSVP, rJS, Handlebars) { (function (window, document, RSVP, rJS, Handlebars, initGadgetMixin) {
"use strict"; "use strict";
/*jslint nomen: true*/ /*jslint nomen: true*/
var gadget_klass = rJS(window), var gadget_klass = rJS(window),
...@@ -7,38 +7,50 @@ ...@@ -7,38 +7,50 @@
.getElementById('tool-template').innerHTML, .getElementById('tool-template').innerHTML,
tool_template = Handlebars.compile(tool_template_source); tool_template = Handlebars.compile(tool_template_source);
function waitForDragstart(tool) {
/*jslint unparam: true*/
var callback = function (evt) {
evt.dataTransfer.setData('text/html', tool.outerHTML);
};
return new RSVP.Promise(function (resolve, reject) {
tool.addEventListener('dragstart', callback, false);
}, function () {
tool.removeEventListener('dragstart', callback, false);
});
}
initGadgetMixin(gadget_klass);
gadget_klass gadget_klass
.declareAcquiredMethod("getConfigurationDict", "getConfigurationDict") .declareAcquiredMethod("getConfigurationDict", "getConfigurationDict")
.declareMethod("render", function () { .declareMethod("render", function () {
var g = this; var g = this;
return new RSVP.Queue() return g.getConfigurationDict()
.push(function () { .push(function (config_dict) {
return g.getConfigurationDict(); var tools_container = document.createElement('div');
}) tools_container.className = 'tools-container';
.push(function (config) { Object.keys(config_dict).forEach(function (key) {
g.tools_container = document.createElement('div'); var name = config_dict[key].name || key.split('-')[1];
g.tools_container.className = 'tools-container';
Object.keys(config).forEach(function (key) {
var name = config[key].name || key.split('-')[1];
if (key !== 'Dream-Configuration') { if (key !== 'Dream-Configuration') {
g.tools_container.innerHTML += tool_template({ tools_container.innerHTML += tool_template({
key: key, key: key,
name: name name: name
}); });
} }
}); });
g.props.element.querySelector('.tools')
.appendChild(tools_container);
}); });
}) })
.declareMethod('startService', function () { .declareMethod('startService', function () {
var g = this; var promiseArray = [];
return g.getElement().then(function (element) { [].forEach
element.querySelector('.tools') .call(this.props.element.querySelectorAll('.tool'), function (tool) {
.appendChild(g.tools_container); promiseArray.push(waitForDragstart(tool));
}); });
return RSVP.all(promiseArray);
}); });
}(window, document, RSVP, rJS, Handlebars, initGadgetMixin));
}(window, document, RSVP, rJS, Handlebars));
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment