TiledViz
Loading...
Searching...
No Matches
Mesh.js
1
12
13$(document).ready( function (){
14
15 addBlink=function(myButton) {
16 if (typeof(myButton.addClass) == "undefined") {
17 $('#'+myButton.id).addClass('BlinkIcon');
18 } else {
19 myButton.addClass('BlinkIcon');
20 }
21
22 myButtonUnBlink=function(myButton) {
23 if (typeof(myButton.removeClass) == "undefined") {
24 $('#'+myButton.id).removeClass('BlinkIcon');
25 var theId=myButton.id;
26 } else {
27 myButton.removeClass('BlinkIcon');
28 var theId=myButton.prop('id');
29 }
30 //console.log("myButtonUnBlink",theId);
31 }
32 setTimeout(myButtonUnBlink,2000,myButton);
33 };
34
35 // add a short blink on legend if a notification is printed.
36 var notif_observer = new MutationObserver(function(e) {addBlink($(".main-legend-zone"))});
37 notif_observer.observe($('#notifications').get(0), {childList: true, subtree: true});
38
39 // Get style.css StyleSheet Rules
40 var stylesheets = document.styleSheets;
41 var sstyleRuleBorderBlink="";
42 var BorderBlinkColor=false;
43 if (stylesheets) {
44 var sstyle = "";
45 var RuleBorderBlinkId = "";
46 for (var i = 0; i < stylesheets.length; ++i) {
47 if (stylesheets[i].href) {
48 if (stylesheets[i].href.includes("style.css")) {
49 sstyle = stylesheets[i];
50 // Chrome definition
51 try {
52 for (var j = 0; j < sstyle.rules.length; ++j ) {
53 if (sstyle.rules[j].type == 7)
54 if (sstyle.rules[j].cssRules[0].style.cssText.includes("outline-color")) {
55 RuleBorderBlinkId=j;
56 sstyleRuleBorderBlink=sstyle.rules[j].cssRules[0].style;
57 BorderBlinkColor=true;
58 break;
59 }
60 }
61 } catch(err) {
62 // Firefox definition
63 try {
64 for (var j = 0; j < sstyle.cssRules.length; ++j ) {
65 if (sstyle.cssRules[j].cssText.includes("outline-color")) {
66 RuleBorderBlinkId=j;
67 sstyleRuleBorderBlink=sstyle.cssRules[j];
68 BorderBlinkColor=true;
69 break;
70 }
71 }
72 } catch(err1) {
73 // not portable
74 }
75 }
76 }
77 }
78 }
79 }
80
81 addBorderBlink=function(myElem,myColor) {
82 if (typeof(myElem.addClass) == "undefined") {
83 //$('#'+myElem.id).css("outline-color",myColor);
84 if (BorderBlinkColor)
85 sstyleRuleBorderBlink.cssText=sstyleRuleBorderBlink.cssText.replace(/outline-color: .*;/,"outline-color: "+myColor+";");
86 $('#'+myElem.id).addClass('BlinkBorder');
87
88 } else if (typeof(myElem[0]) == "object") {
89 //myElem.css("outline-color",myColor);
90 if (BorderBlinkColor)
91 sstyleRuleBorderBlink.cssText=sstyleRuleBorderBlink.cssText.replace(/outline-color: .*;/,"outline-color: "+myColor+";");
92 myElem.addClass('BlinkBorder');
93 }
94
95 myElemBorderUnBlink=function(myElem) {
96 if (typeof(myElem.removeClass) == "undefined") {
97 $('#'+myElem.id).css("border","hidden");
98 $('#'+myElem.id).removeClass('BlinkBorder');
99 var theId=myElem.id;
100 } else if (typeof(myElem[0]) == "object") {
101 myElem.css("border","hidden");
102 myElem.removeClass('BlinkBorder');
103 var theId=myElem.prop('id');
104 }
105 }
106 setTimeout(myElemBorderUnBlink,2000,myElem);
107 };
108
109 function download(content, fileName, contentType) {
110 var a = document.createElement("a");
111 var file = new Blob([content], {type: contentType});
112 a.href = URL.createObjectURL(file);
113 a.download = fileName;
114 a.click();
115 URL.revokeObjectURL(a.href)
116 }
117 //download(jsonData, 'json.txt', 'text/plain');
118
119 _allowDragAndDrop = true; // block Drag and Drop if false
120 BlockDragAndDrop=function() {
121 _allowDragAndDrop = false;
122 $('.handle').addClass("drag-handle-off").removeClass("drag-handle-on");
123 };
124
125 EnableDragAndDrop=function() {
126 _allowDragAndDrop = true;
127 $('.handle').addClass("drag-handle-on").removeClass("drag-handle-off");
128 }
129
130 function parseBool(val) { return val === true || val === "true" };
131
132Mesh = function(cardinal,NumColumnsConstant,maxNumOfColumns_) {
133
134 $('#legend').html("<h1>Working on "+my_session+"</h1> <h2>Number of nodes : "+cardinal.toString()+"</h2>");
135
136 // Bool to add initial position in tags of each tile
137 var debugPos = false;
138
139 me = this; // Reference to the mesh
140 var nodeCardinal = cardinal; // Number of nodes on the mesh
141 var nodesById = []; // Table containing all the nodes on the mesh indexed by --> "node"+id<--
142 // Example : nodesById ["node"+0] -> get the node with id =0;
143 var nodesByLoc = []; // Table containing all the nodes on the mesh indexed by idLocation
144 // Example : nodesByLoc [0]-> give the node located at the top-left place;
145 var nodesOldPositions = []; // Double table containing position of nodes after each user-made movement
146 // Example : nodesById[5][3] ->gives the idlocation of third (id = 3) node after 5 users actions where node has been moved
147 // To debug nodesByLoc and nodesById :
148 // arr=[]; for (var U in nodesById) { arr.push([nodesById[U].getIdLocation(),U,nodesById[U].getId()]) }; arr
149 // arr.sort((a, b) => a[0] - b[0]).map(x=>x[2]) must be always "equal" to nodesByLoc.map(x=>x.getId())
150 var stepBack=1; // Variable to help managing nodesOldPositions : it is incremented when users go back and decremented when users go forward
151 var lines = []; // Contains references to the first node of each line
152 var columns = []; // Contains references to the first node of each column
153 var numOfLines = []; // Number of lines
154 var numOfColumns = []; // Number of columns
155 var maxNumOfColumns = maxNumOfColumns_; // Maximal number of columns
156 var locationJsonDataConsistency = false ; // Decided in the next function
157 var widthTab = new Array(); // Table indexed by the id: widthtab[theid] contains the width of the picture on the node with id = theid
158 var heightTab = new Array(); // Same for the height
159 var columnSelected = -1 ; // Contains the number of a selected column (first column corresponds to 0)
160 var lineSelected = -1 ; // Contains the number of a selected line (first line corresponds to 0)
161
162 var touchspeed = configBehaviour.touchSpeed; // speed of touch move;
163
164 // Rotation increment
165 var RotInc=0.5;
166 if (parseBool(configBehaviour.smoothRotation)) {
167 RotInc=parseFloat(configBehaviour.RotationSpeed); //for a smooth touchmove rotation
168 } else {
169 // for a turn over with only touchstart / touchend (no touchmove) events
170 RotInc=180;
171 }
172
173
174 var zoomSelection = false;
175 var removingTag = false;
176 var tagToRemove = "";
177 var selectingTags = false;
178 var tagToSelect = "";
179 var alignTags = false;
180 var alignOrderTag=true; // true is increase, false is decrease
181
182 var hideNodesTag = false;
183 var killNodesTag = false;
184 var transparentNode = -1; // Default
185
186 var HideNodesTagFlag=false; // Flag indicated the use of HideTags menu to hide nodes with selected tag in tagMenu.
187
188 var KillNodesTagFlag=false; // Flag indicated the use of KillTag menu to suppress nodes with selected tag in tagMenu.
189 var SelectionMultipleTagsFlag = false; // Flag indicated the use of SelectMultipleTags for grouping tags in a new tag.
190 var seltags=""; // Name of the selection tag if SelectionMultipleTagsFlag = true
191 var SelectionNodeToTagFlag=false; // Flag indicated the use of SelectionNodeToTag menu to add tag for nodes in selection.
192 var PaletteNodeTagFlag=false; // Flag indicated the use of ChoosingColor menu to change tag color with selected tag in tagMenu.
193
194 TagHeight=0; // tag-legend zone height
195
196 // Correct wrong default config
197 if (!! configBehaviour.onlyMasterMS)
198 configBehaviour.onlyMasterMS=false
199 configBehaviour.touchonWindow=false
200
201 // Getter and setter for zoomSelection
202 this.getZoomSelection = function(){
203 return zoomSelection;
204 };
205
206 this.setZoomSelection = function (bool){
207 zoomSelection = bool;
208 };
209
210 // Getter and setter for removingTag
211 this.getRemovingTag = function(){
212 return removingTag;
213 };
214
215 this.setRemovingTag = function(bool){
216 removingTag = bool;
217 };
218
219 this.getTagToRemove = function(){
220 return tagToRemove;
221 };
222
223 this.setTagToRemove = function(text){
224 tagToRemove = text;
225 };
226
227 // Getters and setters for selectingTags
228 this.getSelectTags = function() {
229 return selectingTags;
230 };
231 this.setSelectTags = function(bool){
232 selectingTags = bool;
233 };
234
235 this.getSelectionTag = function() {
236 return SelectionNodeToTagFlag;
237 };
238 this.setSelectionTag = function(bool){
239 SelectionNodeToTagFlag = bool;
240 };
241
242 this.getSelectMultipleTags = function() {
243 return SelectionMultipleTagsFlag;
244 };
245 this.setSelectMultipleTags = function(bool){
246 SelectionMultipleTagsFlag = bool;
247 if (! SelectionMultipleTagsFlag) {
248 $('.closeSelectMultipleTagsButtonIcon').removeClass('closeSelectMultipleTagsButtonIcon').addClass('selectMultipleTagsButtonIcon');
249 }
250 };
251
252
253 this.getTagToSelect = function(){
254 return tagToSelect;
255 };
256
257 this.setTagToSelect = function(text){
258 tagToSelect = text;
259 };
260
261
262 // Getters and setters for alignTags
263 this.getAlignTags = function() {
264 return alignTags;
265 };
266 this.setAlignTags = function(bool){
267 alignTags = bool;
268 };
269
270 // Getters and setters for hideNodesTag
271 this.getHideNodesTag = function() {
272 return hideNodesTag;
273 };
274 this.setHideNodesTag = function(bool){
275 hideNodesTag = bool;
276 };
277
278 this.getHideNodesTagFlag = function() {
279 return HideNodesTagFlag;
280 };
281 this.setHideNodesTagFlag = function(bool){
282 HideNodesTagFlag = bool;
283 };
284
285 // Getters and setters for killNodesTag
286 this.getkillNodesTag = function() {
287 return killNodesTag;
288 };
289 this.setkillNodesTag = function(bool){
290 killNodesTag = bool;
291 };
292
293 this.getKillNodesTagFlag = function() {
294 return KillNodesTagFlag;
295 };
296 this.setKillNodesTagFlag = function(bool){
297 KillNodesTagFlag = bool;
298 };
299
300 // Add Opacity sliders zone
301 $('header').append("<div id=OpacityZone ></div>")
302
303 // Getter and setter for the transparency
304 this.getTransparent = function(){
305 return transparentNode;
306 };
307 this.setTransparent = function(id, state){ // State is true to set the node transparent, false to unset it
308
309 transparentNode = state ? id : -1;
310
311 this.getNode(id).updateHtmlNodeState(state ? 4 : 0);
312 var nodeOpacity = this.getNode(id).getNodeOpacity();
313 $('#'+id).css("opacity", state ? nodeOpacity : 1);
314 $('#'+id).css("z-index", state ? 100 : 0 );
315 $('#tile-opacity-'+id).css("visibility", state ? "visible" : "hidden");
316
317 if (state) {
318 $('#'+id).addClass("transparentNode");
319 for( mi in $('#menu'+id)[0].childNodes ){
320 m=$('#menu'+id)[0].childNodes[mi];
321 if (m.id && m.id.search("option") > -1) {
322 if ( m.className.search("transparentButtonIcon") > -1) {
323 } else {
324 $('#menu'+id+'>#'+m.id).css({visibility : "hidden"});
325 }
326 }
327 }
328 $('#tile-opacity-'+id).append("<input id=tileOpacitySlider"+id+" class=tile-opacity-slider type='range' name=tileOpacitySlider"+id+" min=0 max=100 value="+nodeOpacity*100+">");
329 $('#tileOpacitySlider'+id).off("click").off("mousup");
330 $('#tileOpacitySlider'+id).on({
331 click : function(){
332 var nodeOpacity_ = Math.max($('#tileOpacitySlider'+id).val()/100, 0.1);
333 $('#'+id).css("opacity", nodeOpacity_);
334 },
335 mouseup : function(e) {
336 var nodeOpacity_ = $('#tileOpacitySlider'+id).val()/100;
337 cdata={"room":my_session,"Id":id,"Opacity":nodeOpacity_};
338 socket.emit("change_Opacity", cdata, callback=function(sdata){
339 console.log("socket change Opacity Tag ", cdata);
340 });
341 }
342 });
343 var val = ($('#tileOpacitySlider'+id).val() - $('#tileOpacitySlider'+id).attr('min')) / ($('#tileOpacitySlider'+id).attr('max') - $('#tileOpacitySlider'+id).attr('min'));
344
345 $('#tileOpacitySlider'+id).css('background-image',
346 '-webkit-gradient(linear, left top, right top, '
347 + 'color-stop(' + val + ', rgb(255, 0, 0)), '
348 + 'color-stop(' + val + ', rgb(0, 255, 0))'
349 + ')'
350 );
351 ;
352
353 $('#tileOpacitySlider'+id).change(function () {
354 var val = ($(this).val() - $(this).attr('min')) / ($(this).attr('max') - $(this).attr('min'));
355
356 $(this).css('background-image',
357 '-webkit-gradient(linear, left top, right top, '
358 + 'color-stop(' + val + ', rgb(255, 0, 0)), '
359 + 'color-stop(' + val + ', rgb(0, 255, 0))'
360 + ')'
361 );
362 });
363
364 } else {
365 $('#'+id).removeClass("transparentNode");
366 me.meshEventReStart();
367
368 for( mi in $('#menu'+id)[0].childNodes ){
369 m=$('#menu'+id)[0].childNodes[mi];
370 if (m.id && m.id.search("option") > -1) {
371 if (m.className.search("transparentButtonIcon") > -1) {
372 } else {
373 $('#menu'+id+'>#'+m.id).css({visibility : ""});
374 }
375 }
376 }
377 $('#tile-opacity-'+id).css("visibility", "hidden");
378 me.getNode(id).setNodeOpacity(Math.max($('#tileOpacitySlider'+id).val()/100, 0.1));
379
380 $('#tileOpacitySlider'+id).remove();
381
382 }
383
384 };
385
386
389 ( function(){
390
391 var j = 0;
392 var t = 0;
393 var Ntab = new Array();
394 for(j=0;j<jsDataTab.length;j++) {
395 Ntab.push(j);
396 }
397 for(j=0;j<jsDataTab.length;j++) {
398 if(typeof parseInt(jsDataTab[j].IdLocation) == "number" && Ntab.indexOf(parseInt(jsDataTab[j].IdLocation)) > -1) {
399 Ntab.splice(Ntab.indexOf(parseInt(jsDataTab[j].IdLocation)),1);
400 t++;
401 }
402 }
403 if(t==jsDataTab.length){
404 locationJsonDataConsistency =true;
405 useJsonDataLocation=true;
406
407 } else {
408 locationJsonDataConsistency = false;
409 useJsonDataLocation=false;
410
411 }
412 })();
413
420 var ColumnStyle = "dynamic";
421 ( function(){
422
423 if( !(typeof maxNumOfColumns =='number' && maxNumOfColumns> 2)) {
424 maxNumOfColumns = 10;
425 }
426
427 if( NumColumnsConstant == true ) {
428 ColumnStyle = "static";
429 }
430
431 }());
432
433
434 // Size of the nodes
435 var spread = configBehaviour.spread;
436 // Add 2% in X direction to be able to focus and type characters inside the iframe
437 spread.X = spread.X*1.02;
438
439 var borderSize = configBehaviour.borderSize; // In pixels
440
441 var selectedNodes= new Array();// Table containing all selected nodes (TO DO : see if possible to use the same table for the two mechanisms ?)
442
443 var nodesToToggle = new Array(); // Table to store a node to toggle with another (manipulations with the hitbox)
444
445 var nodesToZoom = new Array(); // Table to store the nodes to zoom on (used with the hitbox and the menu)
446
447 var appliedFilters = new Array();// Table containing all applied filters
448
449 var listedTags = new Array(); // Table containing all user-created tags
450
451 //******nodesToZoom******//
452
453 //--add node to zoom on
454 this.addNodeToZoom = function(node){
455 if (nodesToZoom.indexOf(node)==-1) {
456 nodesToZoom.push(node);
457 }
458 }
459
460 //--remove node to zoom on
461 this.removeNodeToZoom = function(node){
462 nodesToZoom.splice(nodesToZoom.indexOf(node),1);
463 };
464
465 //--getter node selected status table
466 this.getNodesToZoom = function(){
467 return nodesToZoom;
468 };
469
470 //--reset table
471 this.resetNodesToZoom = function(){
472 nodesToZoom = new Array();
473 for (O in nodesByLoc)
474 if (nodesByLoc[O].getNodeInViewportStatus())
475 nodesByLoc[O].sub('hitbox').css({backgroundColor : colorHBdefault});
476
477 return nodesToZoom;
478 };
479
492 this.magnifyingGlass = function(nodeZoomTab,ratio,initSpread,Haswaypoint, initScale){
493 // Size of the support for the zoomed node
494 var initScale_ = initScale || false;
495 if (initScale_) {
496 var supportW = parseInt(window.innerWidth*initScale_)-90;
497 var supportH = parseInt(ratio*(parseInt(window.innerWidth*initScale_)-500));
498 var Zscale=initScale_;
499 } else {
500 var supportW = parseInt(window.innerWidth)-90;
501 var supportH = parseInt(ratio*(parseInt(window.innerWidth)-500));
502 var Zscale=1;
503 }
504
505 // No waypoint by default
506 var Haswaypoint_ = Haswaypoint || false ;
507
508 //waypoints are the object which can detect when a object are entering on screen
509 // see http://imakewebthings.com/waypoints/ for details
510 var waypoint = new Array();
511
512 // Definition of the background $(#superSail)
513 if(nodeZoomTab.length!=0){
514 // (each time tiles are magnified, it will be removed and re-created since it’s not a complex and heavy element)
515 $("body").append('<div id=superSail></div>');
516 $("#superSail").css({ // GLOBALCSS !
517 position : 'absolute',
518 top : TagHeight,
519 left : 0,
520 height : "110%",
521 width : "100%",
522 backgroundColor : "black",
523 opacity : "0.9",
524 zIndex : 200,
525 });
526 $("#superSail").off('touchstart');
527 $("#superSail").off('touchmove');
528 $("#superSail").off('touchend');
529 $('#superSail').append('<div id=buttonUnzoom class=unzoomButtonIcon></div>');
530 $('#buttonUnzoom').css({ // GLOBALCSS !
531 position : "fixed",
532 top : 0 ,
533 left : parseInt($(me.menu.getHtmlMenuSelector()).css("width")),
534 height : 200,
535 width : 200,
536 zIndex : 802,
537 backgroundColor: "rgba(0, 0, 0, 0.95)"
538 });
539
540
541 // unload nodes streams
542 for (O in nodesByLoc)
543 if (nodesByLoc[O].getNodeInViewportStatus())
544 nodesByLoc[O].sub('iframe').hide();
545 // for(O in nodesById) {
546 // nodesById[O].setLoadedStatus(false);
547 // }
548
549 // Additionnal space between columns
550 shiftcol=105
551
552 // Definition of the support $(#zoomSupport) for the node
553 // (only the first time, then it will be hidden and shown again)
554 var supp = document.getElementById("zoomSupport");
555 if (supp==null) {
556 $("body").append('<div id=zoomSupport style="overflow-y: scroll;"></div>');
557 $("#zoomSupport").css({ // GLOBALCSS !
558 position: "fixed",
559 //top: (parseInt(window.innerHeight)-ratio*(parseInt(window.innerWidth)-500))/2,
560 top:Math.max(450,TagHeight+240),
561 left: -shiftcol-50,
562 marginTop: "0",
563 width: "102.5%",
564 height: "98%",
565 backgroundColor : "grey",
566 opacity : "1.",
567 display : "flex",
568 flexWrap: "wrap",
569 zIndex : 201,
570 });
571 $("#zoomSupport").off('touchstart');
572 $("#zoomSupport").off('touchmove');
573 $("#zoomSupport").off('touchend');
574 } else {
575 $('#zoomSupport').show();
576 }
577
578 // Size of the grid
579 // Search for the upper and closest square number of the cardinal of the set of nodes chosen by users
580 var L = Math.min(nodeZoomTab.length,2);
581 if ( nodeZoomTab.length > 12 ) {
582 L = Math.min(nodeZoomTab.length,3);
583 }
584
585 var W = supportW/L;
586 var H = supportH/L;
587
588 //console.log(H, W, supportH, supportW);
589 // Building the grid
590
591 // Number of zoomed elements
592 var NbZ=nodeZoomTab.length
593
594 // Number of lines
595 var NbL=Math.max(NbZ/L,1);
596
597 // space between zoomed tiles
598 var shiftX=60;
599 var shiftY=60;
600
601 var zoomX=W-shiftX;
603 var zoomY=H-shiftY;
604 //-shiftleft
605 // shiftleft=parseInt($('#zoomSupport>#'+id+'>#hitbox'+id).css('width'))
606 var Zscale=H/initSpread.Y;
607
608 shifttop=function(e) { return (H+60)*parseInt(e/L)+shiftY };
609 shiftleft=function(e) { return W*parseInt(e % L)+shiftX };
610
611 // To suppress properly some zoomed node :
612 nodeZoomState=new Array();
613 nodeZoomState.length=NbZ;
614 nodeZoomState.fill(true)
615
616 // Stickers : on click, erase the sticker from the node
617 ZclickSticker = function(){
618 // console.log("sticker clicked", this.id);
619 var splittedId = this.id.split("_");
620 var nodeId = splittedId.pop();
621 var node = me.getNode(nodeId);
622 var zoomed = $('#Zoomed'+nodeId);
623 zoomed.children(".stickers_zone").find('#'+this.id).remove();
624 var nodelev=$('#'+nodeId).css("z-index");
625 $('#'+nodeId).css("z-index",999);
626 thisSticker=$('#'+nodeId).children(".stickers_zone").find('#'+this.id);
627 thisSticker.show();
628 $('#'+nodeId).show();
629 thisSticker.click();
630 $('#'+nodeId).css("z-index",nodelev);
631 };
632
633
634 for(var e=0;e<NbZ;e++){
635
636 thisnode=nodeZoomTab[e];
637 // thisnode.updateSelectedStatus(false);
638
639 id=thisnode.getId();
640 thisnodeId=$("#"+thisnode.getId());
641 var iframe2 = $('#iframe'+id);
642
643 $("body").append('<div id=Zoomed'+e+' class=Zoomed></div>');
644 thiszoom=$("#Zoomed"+e);
645 thiszoom.appendTo("#zoomSupport");
646
647 thiszoom.css({ // GLOBALCSS !
648 position : 'absolute',
649 top : shifttop(e),
650 left : shiftleft(e)+shiftcol,
651 height : H,
652 width : W,
653 backgroundColor : "black",
654 opacity : "1.",
655 zIndex : 220,
656 });
657 // left : shiftleft,
658 // thiszoom.off('touchstart');
659 // thiszoom.off('touchmove');
660 // thiszoom.off('touchend');
661
662 // Copy iframe src from initial node
663 iframesrc=thisnode.getJsonData().url;
664
665 //htmlPrimaryParent.append('<div id='+id+' class='+className+'></div>');
666
667 //iframe2=$("#iframe"+id); if (iframe2.is(':visible'))
668 thiszoom.append('<iframe id=Ziframe'+e+' height="'+initSpread.Y+'px" width="'+initSpread.X+'px" position="relative"'+' scrolling="yes"'+' frameborder=0'+' src=""></iframe>');
669
670 if ( Haswaypoint_ ) {
671
672 waypoint[e] = new Waypoint({
673
674 offset : 'bottom-in-view' ,
675 element: document.getElementById("Zoomed"+e),
676
677 handler: ( function(){
678
679 var id = e;
680 var iframesrc_=iframesrc;
681 return function(direction) {
682 if (direction == "down") {
683 iframe2=$('#Ziframe'+id);
684 if (iframe2.attr("src")=="")
685 iframe2.attr("src",iframesrc_);
686 waypoint[id].destroy();
687 } else {
688 iframe2=$('#Ziframe'+id);
689 if (iframe2.attr("src")=="")
690 iframe2.attr("src",iframesrc_);
691 waypoint[id].destroy();
692 }
693 };
694
695 })()
696
697 });
698 } else
699 $('#Ziframe'+e).attr("src",iframesrc);
700
701 // Copy info from initial node
702 var Zinfo=thisnodeId.children(".info").clone().css('display','block').appendTo("#Zoomed"+e);
703 Zinfo[0].id="Z"+Zinfo[0].id;
704
705 Zframe=$('#Ziframe'+e);
706 Zframe.css('-webkit-transform','scale('+Zscale+')').css('-moz-transform','scale('+Zscale+')');
707 // Zframe.off('touchstart');
708 // Zframe.off('touchmove');
709 // Zframe.off('touchend');
710
711 Zinfo.css('-webkit-transform','scale('+Zscale/2+')').css('-moz-transform','scale('+Zscale/2+')');
712 Zinfo.css('top',"-60px").css("left",zoomX*1./2).css("position","absolute");;
713 Zinfo.show();
714
715 // Copy sticker zone
716 var Zsticker=thisnodeId.children(".stickers_zone").clone().css('display','block').appendTo("#Zoomed"+e);
717 Zsticker[0].id="Z"+Zsticker[0].id;
718
719 // Supress this zoomed node
720 thiszoom.prepend('<div id="Zclose'+e+'" class=unzoomButtonIcon></div>');
721 Zclose=$('#Zclose'+e);
722 Zclose.css({
723 position: 'absolute',
724 height:200,
725 width: 200,
726 left: spread.X*Zscale,
727 top: 0,
728 zIndex:400,
729 '-webkit-transform':'scale('+Zscale/4+')',
730 '-moz-transform':'scale('+Zscale/4+')'
731 });
732 Zclose.on("click",function() {
733 var e = parseInt(this.id.replace("Zclose",""));
734 $("#Zoomed"+e).remove();
735 nodeZoomState[e]=false;
736 var iter=0;
737 for(var ee=0;ee<NbZ;ee++){
738 if ( ee != e && nodeZoomState[ee] ) {
739 thiszoom=$("#Zoomed"+ee);
740
741 thiszoom.css({
742 top : shifttop(iter),
743 left : shiftleft(iter)
744 });
745 iter = iter + 1;
746 }
747 }
748 });
749
750 Zsticker.css('-webkit-transform','scale('+Zscale/2+')').css('-moz-transform','scale('+Zscale/2+')');
751 Zsticker.css({
752 left: spread.X*Zscale+80,
753 top: (parseInt(Zclose.css("top"))+
754 parseInt(Zclose.css("height")))*Zscale,
755 position: "absolute",
756 display: "block",
757 zIndex:999
758 });
759 Zsticker.children('.sticker').on({
760 click : ZclickSticker
761 });
762 }
763 }
764
765 // Add zoom slider
766 var zoomValue = $('#zoomSupport').children(".Zoomed").children("iframe").css("transform");
767 zoomValue = zoomValue.replace("matrix(", "").replace(")", "").split(",")[0];
768 //console.log("zoom value", zoomValue);
769 $('#superSail').append("<div id=zoom-slider-label>Zoom level</div>")
770 .append("<input id=zoomSlider name=zoomSlider class=slider type=range min="+zoomValue/2+" max="+2*zoomValue+" step=0.01 value="+zoomValue+" oninput='zoom.value=zoomSlider.value.toString()'>")
771 .append("<output name=zoom id=zoom class=slider for=zoomSlider>"+zoomValue+"</output>");
772
773 $('#zoomSlider').change(function () {
774 var val = ($(this).val() - $(this).attr('min')) / ($(this).attr('max') - $(this).attr('min'));
775
776 $(this).css('background-image',
777 '-webkit-gradient(linear, left top, right top, '
778 + 'color-stop(' + val + ', rgb(255, 0, 0)), '
779 + 'color-stop(' + val + ', rgb(0, 255, 0))'
780 + ')'
781 );
782 });
783 $('#zoom-slider-label').css({
784 position : "fixed",
785 fontSize : "150px",
786 top :0,
787 left : "50%",
788 color : "white",
789 backgroundColor: "rgba(0, 0, 0, 1)"
790 });
791 $('#zoomSlider').css({
792 position : "fixed",
793 top : parseInt($('#buttonUnzoom').css("height")),
794 left : "60%",
795 width : 30/100 * parseInt($('header').css("width")),
796 backgroundColor: "rgba(0, 0, 0, 1)"
797 });
798 var val = (zoomValue - $('#zoomSlider').attr('min')) / ($('#zoomSlider').attr('max') - $('#zoomSlider').attr('min'));
799
800 $('#zoomSlider').css('background-image',
801 '-webkit-gradient(linear, left top, right top, '
802 + 'color-stop(' + val + ', rgb(255, 0, 0)), '
803 + 'color-stop(' + val + ', rgb(0, 255, 0))'
804 + ')'
805 );
806 $('#zoom').css({
807 position: "fixed",
808 fontSize : "150px",
809 left : parseInt($('#zoomSlider').css("width")) + parseInt($('#zoomSlider').css("left")),
810 top: 0,
811 color: "white",
812 zIndex: 802,
813 padding: "0px 50px",
814 backgroundColor: "black"
815 });
816 //$('#zoom').css('background-image','none');
817
818 $('#zoomSlider').on({
819 click : function(e){
820 if ( configBehaviour.sharedSliderZoom && emit_click_val('slider','zoomSlider', $('#zoomSlider').val()) )
821 return
822 if ( configBehaviour.sharedSliderZoom && emit_click_val('slider','zoom', $('#zoomSlider').val()) )
823 return
824
825 var newZoom = $('#zoomSlider').val();
826 $('#zoom').val(newZoom);
827 var ratio = newZoom/zoomValue;
828 $('#zoomSupport').css("-moz-transform","scale("+ratio+")").css("-webkit-transform","scale("+ratio+")").css("transform-origin", "0 0 0");
829 e.stopPropagation(); // To stay on zoomSupport
830 }
831
832
833 });
834
835 // unZoom function
836 $('#buttonUnzoom').on('click',function(){
837
838 $("#superSail").remove();
839 $("#zoomSupport").hide();
840 $('#zoomSupport').css("-moz-transform","scale(1)").css("-webkit-transform","scale(1)").css("transform-origin", "0 0 0");
841 $('#zoomSupport').children(".Zoomed").remove();
842 $("#buttonUnzoom").off();
843 $("#buttonUnzoom").remove();
844
845 // TODO : only on and visible
846 for (O in nodesByLoc)
847 if (nodesByLoc[O].getNodeInViewportStatus()) {
848 nodesByLoc[O].sub('hitbox').off().on("click", clickHBSelect);
849 nodesByLoc[O].sub('iframe').show();
850 }
851 //me.startLoading();
852
853 });
854
855 return Zscale;
856 };
857
858
859
860 var moveMesh = function(direction) {
861 numOfLines = Math.floor(nodeCardinal / numOfColumns);
862 numOfLines = Math.min(numOfLines, nodeCardinal);
863
864 me.computeNumColumns();
865 for (var i=0;i<(numOfLines-1);i++) {
866 //console.log(i, numOfLines);
867 if (direction == "up") {
868 //console.log("going up", i);
869 var firstLine = i;
870 var secondLine = i+1 == numOfLines ? 0 : i+1;
871 }
872 else if (direction == "down") {
873 //console.log("going down", i);
874 var firstLine = numOfLines - 1 - i;
875 var secondLine = numOfLines - 2 - i;
876 }
877
878 var firstLineTab = new Array();
879 var secondLineTab = new Array();
880
881 for (O in nodesByLoc) {
882 if (me.mlocationProvider(nodesByLoc[O].getIdLocation()).getnY() == firstLine ) {
883 firstLineTab.push(nodesByLoc[O]);
884 }
885 else if (me.mlocationProvider(nodesByLoc[O].getIdLocation()).getnY() == secondLine ) {
886 secondLineTab.push(nodesByLoc[O]);
887 }
888 }
889 for (var j=0; j<Math.max(firstLineTab.length, secondLineTab.length);j++) {
890 var tmpBoolBlockMove = j == 0 ? false : true;
891 if(typeof firstLineTab[j]!= "undefined" && typeof secondLineTab[j]!= "undefined" ) {
892 me.switchLocation(firstLineTab[j],secondLineTab[j],configBehaviour.showAnimationsLineColSwap, true, tmpBoolBlockMove);
893 }
894 }
895 }
896 for (O in nodesByLoc) {
897 if (nodesByLoc[O].getNodeInViewportStatus()) {
898 //nodesByLoc[O].getOnOffStatus() &&
899 SetOn(nodesByLoc[O].getId());
900 } else {
901 SetOff(nodesByLoc[O].getId());
902 }
903 }
904 // for (O in nodesByLoc)
905 // console.log(O,nodesByLoc[O].getId(),nodesByLoc[O].getIdLocation(),nodesByLoc[O].getHtmlNode().children("iframe"))
906 };
907
908 // Refresh nodes function
909
910 refreshNodes = function (node) {
911
912 // check if optionnal argument node is present (node can be "0" == false in javascript)
913 var hasNoNode=false
914 if (typeof(node) == "undefined")
915 hasNoNode = true
916
917 //console.log("test refresh");
918
919 if (hasNoNode) {// ie no node specified -> refresh all nodes
920 for (O in nodesByLoc) {
921 nodesByLoc[O].setNodeInViewportStatus()
922 if (nodesByLoc[O].getNodeInViewportStatus()) {
923 me.loadContent(O);
924 SetOn(nodesByLoc[O].getId());
925 } else {
926 SetOff(nodesByLoc[O].getId());
927 }
928 // nodesByLoc[O].getHtmlNode().children('iframe')[0].setAttribute("src","");
929 // nodesByLoc[O].getHtmlNode().children('iframe')[0].setAttribute("src",nodesByLoc[O].getJsonData().url);
930 }
931
932 for (O in nodesById) {
933 me.unsetDraggable(nodesById[O].getId(), false, false);
934 }
935
936 // Onnodes = $('.On').parent().parent().children('iframe');
937 // for (node in Onnodes) {
938 // if (node != "prevObject" && typeof Onnodes[node] == "object"
939 // && nodesByLoc[Onnodes[node].parentElement.id].getLoadedStatus()) {
940 // Onnodes[node].setAttribute("src","")
941 // Onnodes[node].setAttribute("src",nodesById["node"+Onnodes[node].parentElement.id].getJsonData().url);
942 // }
943 // }
944 // for (node in Onnodes) {
945 // if (node != "prevObject" && typeof Onnodes[node] == "object") {
946 // Onnodes[node].setAttribute("src",oldSrc[node]);
947 // }
948 // }
949 } else {
950 nodesByLoc[node].setNodeInViewportStatus()
951 me.unsetDraggable(node);
952 }
953 me.meshEventReStart();
954
955 EnableDragAndDrop();
956 };
957
958 receive_deploy_Selection=false
959 socket.on('receive_deploy_Selection', function(sdata){
960 console.log("receive_deploy_Selection",sdata);
961 var listSelectionIds = eval(sdata["Selection"]);
962 for (O in listSelectionIds) {
963 var HB = $('#hitbox' + listSelectionIds[O]);
964 var node = nodesById["node"+listSelectionIds[O]];
965 node.updateSelectedStatus(true);
966 me.addNodeToZoom(node);
967 HB.css({backgroundColor : colorHBtoZoom});
968 }
969 receive_deploy_Selection=true
970 });
971
972 // Update the Mesh
973 socket.on('receive_deploy_nodes', function(sdata){
974 console.log("receive_deploy_nodes",sdata);
975 var jsDataTab_mod = sdata["modtiles_data"]; // modtiles_data.append([tile1,tile2])
976
977 // modifiy some nodes
978 for ( idadd in jsDataTab_mod ) {
979 var tile1=jsDataTab_mod[idadd][0]
980 var tile2=jsDataTab_mod[idadd][1]
981 for (O in nodesById) {
982 var node=nodesById[O];
983 var Id=node.getId();
984 if (node.getJsonData()["url"] == tile2["url"]) {
985
986 var newTags=node.updatedata(tile2);
987
988 // update global Tags ?
989 for (var itag in newTags) {
990 me.AddNewTag(newTags[itag]);
991 }
992 }
993 }
994 }
995
996
997 refreshNodes();
998 //me.meshEventStart();
999 me.meshEventReStart();
1000 me.startLoading();
1001
1002 // update search list
1003 suggestion_list = globalTagsList
1004 .concat($('.info').map(function(){ return $.trim($(this).text());}).get())
1005 .concat(Object.keys(nodesById).map(function(e){return $.trim(nodesById[e].getJsonData().comment); }));
1006 });
1007
1038
1046
1047 var tagMenuTitleTab = new Array();
1048 var tagMenuEventTab = new Array();
1049 var tagMenuIconClassAttributesTab = new Array();
1050 var tagMenuShareEvent = new Array();
1051
1052 var tagAlignOrderTagsMenuTitleTab = new Array();
1053 var tagAlignOrderTagsMenuEventTab = new Array();
1054 var tagAlignOrderTagsMenuIconClassAttributesTab = new Array();
1055 var tagAlignOrderTagsMenuShareEvent = new Array();
1056
1057 var tagHideTagsMenuTitleTab = new Array();
1058 var tagHideTagsMenuEventTab = new Array();
1059 var tagHideTagsMenuIconClassAttributesTab = new Array();
1060 var tagHideTagsMenuShareEvent = new Array();
1061
1062 var tagKillTagsMenuTitleTab = new Array();
1063 var tagKillTagsMenuEventTab = new Array();
1064 var tagKillTagsMenuIconClassAttributesTab = new Array();
1065 var tagKillTagsMenuShareEvent = new Array();
1066
1067 var tagSelectionMenuTitleTab = new Array();
1068 var tagSelectionMenuEventTab = new Array();
1069 var tagSelectionMenuIconClassAttributesTab = new Array();
1070 var tagSelectionMenuShareEvent = new Array();
1071
1072 var tagManagementMenuTitleTab = new Array();
1073 var tagManagementMenuEventTab = new Array();
1074 var tagManagementMenuIconClassAttributesTab = new Array();
1075 var tagManagementMenuShareEvent = new Array();
1076
1077 var EndOfGroupping=false;
1078 // User interaction
1079 // Tags
1080 clickTagInLegend = function(){
1081 if (! PaletteNodeTagFlag)
1082 if (emit_click("tag",this.id))
1083 return
1084 if(me.getRemovingTag()) {
1085 var tagToRemove = document.getElementById(this.id);
1086 for(O in nodesByLoc) {
1087 nodesByLoc[O].removeElementFromNodeTagList(this.id);
1088 }
1089 $('#tag-notif').text("Tag " + this.id + " removed from tag list and tiles.");
1090 $('.tag#'+this.id).remove();//removeChild(tagToRemove);
1091 var idTag=globalTagsList.indexOf(this.id)
1092 var name=globalTagsList[idTag];
1093 delete globalTagsColors[name];
1094 globalTagsList.splice(idTag,1);
1095 currentSelectedTag = "";
1096
1097 } else if (me.getSelectTags()) {
1098 var tagToSelect = this.id;
1099 var w = 0;
1100 for (O in nodesById) {
1101 if (me.hasTag(nodesById[O], tagToSelect)) {
1102 var HB = $('#hitbox' + nodesById[O].getId());
1103 nodeSelect(nodesById[O],HB);
1104 w ++;
1105 }
1106 }
1107 if (w==0){
1108 $('#tag-notif').text("No matching tiles for tag " + tagToSelect + " found");
1109 } else {
1110 $('#tag-notif').text(w + " matching tiles for tag " + tagToSelect + " found");
1111 addBlink(this);
1112 }
1113
1114 } else if (me.getAlignTags()) {
1115 var thisTagToGroup = this.id;
1116 var w = 0;
1117 var floatT=[]
1118 var hasFloatingT=false
1119 for (O in nodesById) {
1120 if (me.hasTag(nodesById[O], thisTagToGroup)) {
1121 if (me.hasFloatingTag(nodesById[O], thisTagToGroup)) {
1122 hasFloatingT=true;
1123 floatT[w]=[nodesById[O].getFloatingTag()[thisTagToGroup]["val"],O,nodesById[O].getId()];
1124 } else {
1125 mesh.switchLocation(nodesById[O], nodesByLoc[w], false, true);
1126 };
1127 w ++;
1128 }
1129 }
1130 if (hasFloatingT) {
1131 var sfloatT = Array.from(floatT);
1132 if (alignOrderTag) {
1133 sfloatT.sort((a, b) => a[0] - b[0]);
1134 } else {
1135 sfloatT.sort((a, b) => b[0] - a[0]);
1136 }
1137 for (var w=0; w<sfloatT.length;w++) {
1138 var O=sfloatT[w][1];
1139 mesh.switchLocation(nodesById[O], nodesByLoc[w], false, true);
1140 }
1141 }
1142
1143 if (w==0){
1144 $('#tag-notif').text("No matching tiles for tag " + thisTagToGroup + " found");
1145 } else {
1146 $('#tag-notif').text(w + " matching tiles for tag " + thisTagToGroup + " found");
1147 addBlink(this);
1148 }
1149
1150 if(chargeAllContentOnStart==false) {
1151 me.computeNumColumns();
1152 for(O in nodesById){
1153 node = nodesById[O];
1154 if( node.getLoadedStatus() == false && mesh.locationProvider(node.getIdLocation()).getY()<window.innerHeight ) {
1155 //console.log(node.getmLocation().getnX());
1156 ratio=mesh.loadContent(node.getId());
1157 //node.setLoadedStatus(true);
1158 }
1159 }
1160 }
1161 for (O in nodesByLoc) {
1162 if (nodesByLoc[O].getNodeInViewportStatus()) {
1163 //nodesByLoc[O].getOnOffStatus() &&
1164 SetOn(nodesByLoc[O].getId());
1165 } else {
1166 SetOff(nodesByLoc[O].getId());
1167 }
1168 }
1169 EndOfGroupping=true;
1170
1171 } else if (me.getHideNodesTagFlag()) {
1172 var thisTagToGroup = this.id;
1173 if (me.getHideNodesTag()) {
1174 // Hide nodes for this tag
1175 for (O in nodesByLoc) {
1176 if (me.hasTag(nodesByLoc[O], thisTagToGroup)) {
1177 Id=nodesByLoc[O].getId();
1178 SetOff(Id);
1179 }
1180 }
1181 $('#tag-notif').text("Hiding the tiles bearing " + thisTagToGroup + " tag. (To make them visible again, click on the icon in the tag menu, then on the tag again)")
1182 addBlink(this);
1183 } else {
1184 // Show nodes for this tag
1185 var thisTagToGroup = this.id;
1186 for (O in nodesByLoc) {
1187 if (me.hasTag(nodesByLoc[O], thisTagToGroup)) {
1188 Id=nodesByLoc[O].getId();
1189 SetOn(Id);
1190 }
1191 }
1192 $('#tag-notif').text("Showing the tiles bearing " + thisTagToGroup + " tag.")
1193 addBlink(this);
1194 }
1195 } else if (KillNodesTagFlag) {
1196 var tagToKill = this.id;
1197 // Kill nodes for this tag
1198 for (O in nodesByLoc) {
1199 if (me.hasTag(nodesByLoc[O], tagToKill)) {
1200 Id=nodesByLoc[O].getId();
1201 nodeCardinal--;
1202 node=$('#'+Id);
1203 SetOff(Id);
1204 nodesByLoc[O].removeElementFromNodeTagList(tagToKill);
1205 nodeEnd=nodesByLoc[nodeCardinal];
1206 mesh.switchLocationShiftColumnLine(nodesByLoc[O],nodeEnd,false,false);
1207 nodesByLoc.splice(nodeCardinal,1);
1208 //node.hide();
1209 }
1210 }
1211 $('#tag-notif').text("Killing the tiles bearing " + tagToKill + " tag.")
1212 $('.tag#'+tagToKill).remove();
1213 addBlink(this);
1214 } else if (SelectionNodeToTagFlag) {
1215 currentSelectedTag = this.id;
1216 // Add tag for nodes in selection
1217 var listSelectionTiles=me.getSelectedNodes()
1218 for(O in listSelectionTiles) {
1219 var HBid = "hitbox"+listSelectionTiles[O].getId();
1220 //clickHBTag(HBid);
1221 listSelectionTiles[O].getStickers().addSticker(currentSelectedTag, attributedTagsColorsArray[currentSelectedTag],true);
1222 listSelectionTiles[O].addElementToNodeTagList(currentSelectedTag);
1223 }
1224 $('#tag-notif').text(" Add selected tiles to tag " + this.id);
1225
1226 addBlink(this);
1227 } else if (SelectionMultipleTagsFlag) {
1228 var thisTag = this.id;
1229 var thisDiv = this;
1230 var color = attributedTagsColorsArray[received_newtag];
1231 var newSelTagDiv = document.getElementById(received_newtag);
1232 var funSelTag = function() {
1233 if (receive_Add_Tag) {
1234 clearInterval(checkEndaddSelTag);
1235 addBlink(thisDiv);
1236 addBlink(newSelTagDiv);
1237
1238 for (O in nodesById) {
1239 if (me.hasTag(nodesById[O], thisTag)) {
1240 nodesById[O].getStickers().addSticker(received_newtag,color);
1241 nodesById[O].addElementToNodeTagList(received_newtag);
1242 }
1243 }
1244 $('#tag-notif').text(" Add tiles from tag " + thisTag + " to selection tag " + received_newtag);
1245 }
1246 }
1247 var checkEndaddSelTag = setInterval(funSelTag, 100);
1248
1249 } else if (PaletteNodeTagFlag) {
1250 var tagToColor = this.id;
1251 var colorChoose;
1252 var defaultColor = colourNameToHex(configBehaviour.draw.defaultColor);
1253 colorChoose = document.querySelector("#colorChoose");
1254 colorChoose.value = defaultColor;
1255
1256 $('#'+tagToColor).css("outline-style", "solid");
1257
1258 var TagColor = defaultColor;
1259
1260 window["updateFirst"+tagToColor] = function (event) {
1261 TagColor = event.target.value;
1262 }
1263 window["updateAll"+tagToColor] = function (event) {
1264 $('#'+tagToColor).css("outline-style", "none");
1265 cdata={"room":my_session,"OldTag":tagToColor,"TagColor":TagColor};
1266 socket.emit("color_Tag", cdata, callback=function(sdata){
1267 console.log("socket change color Tag ", cdata);
1268 });
1269 colorChoose.removeEventListener("input", window["updateFirst"+tagToColor]);
1270 colorChoose.removeEventListener("change", window["updateAll"+tagToColor]);
1271 delete window["updateFirst"+tagToColor];
1272 delete window["updateAll"+tagToColor];
1273 }
1274
1275 colorChoose.addEventListener("input", window["updateFirst"+tagToColor], false);
1276 colorChoose.addEventListener("change", window["updateAll"+tagToColor], false);
1277 colorChoose.select();
1278
1279 } else { // DEFAULT behaviour: click on a tag = make it ready to be given to a tile
1280 if (currentSelectedTag != this.id) { // Click on a different tag than the previous one
1281 $('#'+this.id).css("outline", "10px solid white");
1282 $('#'+this.id).css("z-index", 500);
1283 if (currentSelectedTag != "") { // Previous tag was existing (and not blank) : un-select it
1284 $('#'+currentSelectedTag).css("outline-style", "none");
1285 $('#'+currentSelectedTag).css("z-index", 149);
1286 }
1287 currentSelectedTag = this.id;
1288 $('#tag-notif').text("Selected tag: " + currentSelectedTag + "; you may now click on the left border of a tile to give it the tag.");
1289 }
1290 else // Un-select current tag
1291 {
1292 $('#'+this.id).css("outline-style", "none");
1293 $('#'+this.id).css("z-index", 149);
1294 currentSelectedTag = "";
1295 $('#tag-notif').text("No selected tag.");
1296 }
1297 addBlink(this);
1298 }
1299 };
1300
1301 // Stickers : on click, erase the sticker from the node
1302 clickSticker = function(){
1303 //console.log("sticker clicked", this.id);
1304 if (emit_click("sticker",this.id))
1305 return
1306 var splittedId = this.id.split("_");
1307 var nodeId = splittedId.pop();
1308 var node = nodesById["node"+nodeId];
1309 node.removeElementFromNodeTagList(splittedId.join("_"));
1310 };
1311
1312 // Add a tag
1313 this.AddNewTag=function(tmpNewTag) {
1314 var k = -1;
1315 if ( $.inArray(tmpNewTag, globalTagsList) == -1 ) {
1316 globalTagsList.push(tmpNewTag);
1317 var k = globalTagsList.length -1;
1318 var l = k;
1319 globalTagsColors[tmpNewTag]={"l":l};
1320 } else {
1321 var k = globalTagsList.indexOf(tmpNewTag);
1322 var l = globalTagsColors[tmpNewTag]["l"];
1323 }
1324 $('#tag-legend').append('<div id =' + globalTagsList[k] + ' class=tag>' + globalTagsList[k] + '</div>');
1325 var thisNewTagFun=function() {
1326 try {
1327 var A=$('#'+globalTagsList[k]).position();
1328 clearInterval(TagPosFun);
1329
1330 if ($('#'+globalTagsList[k]).position().left==0) {
1331 $("#tag-legend").css({ height: $("#tag-legend").height()+$('#'+globalTagsList[k]).height() });
1332 }
1333 try {
1334 $('#'+globalTagsList[k]).css('background-color',ColorSticker(l));
1335 attributedTagsColorsArray[globalTagsList[k]] =$('#'+globalTagsList[k]).css("background-color");
1336 $('#tag-notif').text("New tag added: " + tmpNewTag);
1337 }
1338 catch(err) {
1339 $('#tag-legend div:last').remove();
1340 console.log("Tag not valid", tmpNewTag);
1341 $('#tag-notif').text("Invalid tag: " + tmpNewTag + ", please try again.");
1342 }
1343
1344 TagHeight=($("#tag-legend").height());
1345
1346 if ( my_user != "Anonymous" ) {
1347 TopPP=TagHeight;
1348 htmlPrimaryParent.css("marginTop",TopPP+"px");
1349 ppot=TopPP;
1350 }
1351 $('.tag').off("click").on({
1352 click : clickTagInLegend
1353 });
1354 } catch(err) {
1355 //Not Yet
1356 }
1357 };
1358 var TagPosFun = setInterval( thisNewTagFun, 100);
1359 }
1360
1361 // Color tag
1362 this.ChangeColorTag = function(thisTag, NewColor) {
1363 $('#'+thisTag).css('background-color',NewColor);
1364 attributedTagsColorsArray[thisTag] = NewColor;
1365 for (O in nodesByLoc) {
1366 if (me.hasTag(nodesByLoc[O], thisTag)) {
1367 nodesByLoc[O].getStickers().colorSticker(thisTag,NewColor);
1368 }
1369 }
1370 }
1371
1374 this.disableOtherTagFunction = function (mytagfunction) {
1375 var ListTagFunction=["AlignTags","HideNodesTagFlag","KillNodesTagFlag","SelectTags","SelectionTag","SelectMultipleTags"];
1376 for (var otherTag in ListTagFunction) {
1377 var thisTag=ListTagFunction[otherTag];
1378 if ( thisTag != mytagfunction )
1379 eval("me.set"+thisTag+"(false)");
1380 }
1381 eval("me.set"+mytagfunction+"(true)");
1382 };
1383
1384 // Align/group similarly tagged nodes
1385 tagMenuTitleTab.push("Align/group similarly tagged nodes")
1386 tagMenuEventTab.push( function(v, id, optionNumber){
1387 if(v==true) {
1388 //console.log("grouping tags");
1389 me.disableOtherTagFunction("AlignTags");
1390 me.setAlignTags(true);
1391 $('#'+id+'option'+optionNumber).removeClass('alignTagButtonIcon').addClass('closeAlignTagButtonIcon');
1392 } else {
1393 //console.log("end grouping tag");
1394 me.setAlignTags(false);
1395 $('#'+id+'option'+optionNumber).removeClass('closeAlignTagButtonIcon').addClass('alignTagButtonIcon');
1396 }
1397 });
1398 tagMenuIconClassAttributesTab.push("alignTagButtonIcon");
1399 tagMenuShareEvent.push(true);
1400
1401 // Align/group similarly tagged nodes
1402 tagMenuTitleTab.push("Order floatting tagged nodes")
1403 tagMenuEventTab.push( function(v, id, optionNumber){
1404 if(v==true) {
1405 //console.log("align order tags");
1406 $('#'+id+'option'+(optionNumber-1)).click();
1407 menuAlignOrderTags
1408 .css("top",menuTags.position()["top"]+200)
1409 .css("left",$('.alignOrderTagsMenuButtonIcon').position()["left"]+menuTags.position()["left"])
1410 .css("visibility", "visible");
1411 $('#'+id+'option'+optionNumber).removeClass('alignOrderTagsMenuButtonIcon').addClass('closeAlignOrderTagsMenuButtonIcon');
1412 } else {
1413 //console.log("end align order tag");
1414 menuAlignOrderTags.css("visibility", "hidden");
1415 $('#'+id+'option'+optionNumber).removeClass('closeAlignOrderTagsMenuButtonIcon').addClass('alignOrderTagsMenuButtonIcon');
1416 }
1417 });
1418 tagMenuIconClassAttributesTab.push("alignOrderTagsMenuButtonIcon");
1419 tagMenuShareEvent.push(true);
1420
1421 tagAlignOrderTagsMenuTitleTab.push("Increasing sort")
1422 tagAlignOrderTagsMenuEventTab.push( function(v, id, optionNumber){
1423 me.disableOtherTagFunction("AlignTags");
1424 me.setAlignTags(true);
1425 if(v==true) {
1426 //console.log("Align order decrease");
1427 $('#'+id+'option'+optionNumber).removeClass('increaseOrderTagsButtonIcon').addClass('closeIncreaseOrderTagsButtonIcon');
1428 $('#'+id+'option'+(optionNumber+1)).removeClass('decreaseOrderTagsButtonIcon').addClass('closeDecreaseOrderTagsButtonIcon');
1429 alignOrderTag=false
1430 } else {
1431 //console.log("Align order increase");
1432 $('#'+id+'option'+optionNumber).removeClass('closeIncreaseOrderTagsButtonIcon').addClass('increaseOrderTagsButtonIcon');
1433 $('#'+id+'option'+(optionNumber+1)).removeClass('closeDecreaseOrderTagsButtonIcon').addClass('decreaseOrderTagsButtonIcon');
1434 alignOrderTag=true
1435 }
1436 });
1437 tagAlignOrderTagsMenuIconClassAttributesTab.push('increaseOrderTagsButtonIcon')
1438 tagAlignOrderTagsMenuShareEvent.push(true);
1439
1440 tagAlignOrderTagsMenuTitleTab.push("Decreasing sort")
1441 tagAlignOrderTagsMenuEventTab.push( function(v, id, optionNumber){
1442 me.disableOtherTagFunction("AlignTags");
1443 me.setAlignTags(true);
1444 if(v==true) {
1445 //console.log("Align order increase");
1446 $('#'+id+'option'+optionNumber).removeClass('decreaseOrderTagsButtonIcon').addClass('closeDecreaseOrderTagsButtonIcon');
1447 $('#'+id+'option'+(optionNumber-1)).removeClass('increaseOrderTagsButtonIcon').addClass('closeIncreaseOrderTagsButtonIcon');
1448 alignOrderTag=false
1449 } else {
1450 //console.log("Align order decrease");
1451 $('#'+id+'option'+optionNumber).removeClass('closeDecreaseOrderTagsButtonIcon').addClass('decreaseOrderTagsButtonIcon');
1452 $('#'+id+'option'+(optionNumber-1)).removeClass('closeIncreaseOrderTagsButtonIcon').addClass('increaseOrderTagsButtonIcon');
1453 alignOrderTag=true
1454 }
1455 });
1456 tagAlignOrderTagsMenuIconClassAttributesTab.push('decreaseOrderTagsButtonIcon')
1457 tagAlignOrderTagsMenuShareEvent.push(true);
1458
1459
1460
1461 // Hide/Show nodes with tags menu
1462 tagMenuTitleTab.push("Hide/Show nodes with tags menu")
1463 tagMenuEventTab.push( function(v, id, optionNumber){
1464 if(v==true) {
1465 menuHideTags
1466 .css("top",menuTags.position()["top"]+200)
1467 .css("left",$('.hideTagsMenuButtonIcon').position()["left"]+menuTags.position()["left"])
1468 .css("visibility", "visible");
1469 $('#'+id+'option'+optionNumber).removeClass('hideTagsMenuButtonIcon').addClass('closeHideTagsMenuButtonIcon');
1470 } else {
1471 me.tagHideTagsMenu.closeAllOptions();
1472 menuHideTags.css("visibility", "hidden");
1473 $('#'+id+'option'+optionNumber).removeClass('closeHideTagsMenuButtonIcon').addClass('hideTagsMenuButtonIcon');
1474 }
1475 });
1476 tagMenuIconClassAttributesTab.push("hideTagsMenuButtonIcon");
1477 tagMenuShareEvent.push(true);
1478
1479 tagHideTagsMenuTitleTab.push("Hide nodes")
1480 tagHideTagsMenuEventTab.push( function(v, id, optionNumber){
1481 if(v==true) {
1482 //console.log("Hide nodes with tags");
1483 me.disableOtherTagFunction("HideNodesTagFlag");
1484 me.setHideNodesTagFlag(true);
1485 me.setHideNodesTag(true);
1486 $('#'+id+'option'+optionNumber).removeClass('hideTagsButtonIcon').addClass('closeHideTagsButtonIcon');
1487 } else {
1488 //console.log("Show nodes with tags");
1489 me.setHideNodesTagFlag(false);
1490 me.setHideNodesTag(false);
1491 $('#'+id+'option'+optionNumber).removeClass('closeHideTagsButtonIcon').addClass('hideTagsButtonIcon');
1492 }
1493 });
1494 tagHideTagsMenuIconClassAttributesTab.push('hideTagsButtonIcon')
1495 tagHideTagsMenuShareEvent.push(true);
1496
1497 tagHideTagsMenuTitleTab.push("Show nodes")
1498 tagHideTagsMenuEventTab.push( function(v, id, optionNumber){
1499 if(v==true) {
1500 //console.log("Hide nodes with tags");
1501 me.setHideNodesTagFlag(true);
1502 me.setHideNodesTag(false);
1503 $('#'+id+'option'+optionNumber).removeClass('showTagsButtonIcon').addClass('closeShowTagsButtonIcon');
1504 } else {
1505 //console.log("Show nodes with tags");
1506 me.disableOtherTagFunction("HideNodesTagFlag");
1507 $('#'+id+'option'+optionNumber).removeClass('closeShowTagsButtonIcon').addClass('showTagsButtonIcon');
1508 me.setHideNodesTagFlag(false);
1509 me.setHideNodesTag(true);
1510 }
1511 });
1512 tagHideTagsMenuIconClassAttributesTab.push('showTagsButtonIcon')
1513 tagHideTagsMenuShareEvent.push(true);
1514
1515 // Kill nodes with selected tags menu
1516 tagMenuTitleTab.push("Kill tiles with selected tag")
1517 tagMenuEventTab.push( function(v, id, optionNumber){
1518 if(v==true) {
1519 //console.log("Kill nodes with tags");
1520 me.disableOtherTagFunction("KillNodesTagFlag");
1521 $('#'+id+'option'+optionNumber).removeClass('KillTagButtonIcon').addClass('closeKillTagButtonIcon');
1522 } else {
1523 mesh.globalLocationProvider();
1524 me.setKillNodesTagFlag(false);
1525 //console.log("Show nodes with tags");
1526 $('#'+id+'option'+optionNumber).removeClass('closeKillTagButtonIcon').addClass('KillTagButtonIcon');
1527 }
1528 });
1529 tagMenuIconClassAttributesTab.push("KillTagButtonIcon");
1530 tagMenuShareEvent.push(true);
1531
1532 // Selection sub-menu.
1533 tagMenuTitleTab.push("Selection menu.")
1534 tagMenuEventTab.push( function(v, id, optionNumber){
1535 if(v==true) {
1536 menuSelectionTags
1537 .css("top",menuTags.position()["top"]+200)
1538 .css("left",$('.selectTagMenuButtonIcon').position()["left"]+menuTags.position()["left"])
1539 .css("visibility", "visible");
1540 $('#'+id+'option'+optionNumber).removeClass('selectTagMenuButtonIcon').addClass('closeSelectTagMenuButtonIcon');
1541 } else {
1542 me.tagSelectionMenu.closeAllOptions();
1543 menuSelectionTags.css("visibility", "hidden");
1544 $('#'+id+'option'+optionNumber).removeClass('closeSelectTagMenuButtonIcon').addClass('selectTagMenuButtonIcon');
1545 }
1546 });
1547 tagMenuIconClassAttributesTab.push("selectTagMenuButtonIcon");
1548 tagMenuShareEvent.push(true);
1549
1550 // Select similarly tagged nodes for zoom or MS.
1551 tagSelectionMenuTitleTab.push("Select tiles with a tag.")
1552 tagSelectionMenuEventTab.push( function(v, id, optionNumber){
1553 if(v==true) {
1554 //console.log("selecting tags");
1555 me.disableOtherTagFunction("SelectTags");
1556 $('#'+id+'option'+optionNumber).removeClass('selectTagButtonIcon').addClass('closeSelectTagButtonIcon');
1557 } else {
1558 //console.log("end selecting tag");
1559 me.setSelectTags(false);
1560 $('#'+id+'option'+optionNumber).removeClass('closeSelectTagButtonIcon').addClass('selectTagButtonIcon');
1561 }
1562 });
1563 tagSelectionMenuIconClassAttributesTab.push("selectTagButtonIcon");
1564 tagSelectionMenuShareEvent.push(true);
1565
1566 // Add selected tag to all nodes in current selection
1567 tagSelectionMenuTitleTab.push("Add tag for nodes in selection")
1568 tagSelectionMenuEventTab.push( function(v, id, optionNumber){
1569 if(v==true) {
1570 //console.log("Add tag for nodes in selection");
1571 me.disableOtherTagFunction("SelectionTag");
1572 $('#'+id+'option'+optionNumber).removeClass('selectionToTagButtonIcon').addClass('closeSelectionToTagButtonIcon');
1573 } else {
1574 SelectionNodeToTagFlag=false;
1575 $('#'+id+'option'+optionNumber).removeClass('closeSelectionToTagButtonIcon').addClass('selectionToTagButtonIcon');
1576 }
1577 });
1578 tagSelectionMenuIconClassAttributesTab.push("selectionToTagButtonIcon");
1579 tagSelectionMenuShareEvent.push(true);
1580
1581 // Select multiple tags for grouping tags in a new tag.
1582 var SelTags=[]
1583 tagSelectionMenuTitleTab.push("Select tiles with multiple tags.")
1584 tagSelectionMenuEventTab.push( function(v, id, optionNumber){
1585 if(v==true) {
1586 //console.log("selecting multiple tags");
1587 me.disableOtherTagFunction("SelectMultipleTags");
1588
1589 seltags="Sel"+SelTags.length;
1590 SelTags.push(seltags);
1591 console.log("select multiple tags : New Tag ",seltags);
1592 // Here we can't give option to block shareAgain because we have just click on it.
1593 var upMenuTag=$('.closeSelectTagMenuButtonIcon')[0].id;
1594 emit_newTag(upMenuTag,seltags);
1595
1596 $('#'+id+'option'+optionNumber).removeClass('selectMultipleTagsButtonIcon').addClass('closeSelectMultipleTagsButtonIcon');
1597 } else {
1598 //console.log("end selecting multiple tag");
1599 me.setSelectMultipleTags(false);
1600 }
1601 cdata={"room":my_session,"SelTags":seltags,"bool":v};
1602 socket.emit("switch_MultipleTag", cdata, callback=function(sdata){
1603 console.log("Emit switch multiple tags : ", cdata);
1604 });
1605 });
1606 tagSelectionMenuIconClassAttributesTab.push("selectMultipleTagsButtonIcon");
1607 tagSelectionMenuShareEvent.push(false);
1608
1609 socket.on('receive_multiple_Tags', function(sdata){
1610 console.log("receive_multiple_Tags",sdata);
1611 if (Boolean(sdata.bool)) {
1612 me.disableOtherTagFunction("SelectMultipleTags");
1613 seltags=sdata.SelTags;
1614 $('.selectMultipleTagsButtonIcon').removeClass('selectMultipleTagsButtonIcon').addClass('closeSelectMultipleTagsButtonIcon');
1615 } else {
1616 me.setSelectMultipleTags(false);
1617 $('.closeSelectMultipleTagsButtonIcon').removeClass('closeSelectMultipleTagsButtonIcon').addClass('selectMultipleTagsButtonIcon');
1618 }
1619 });
1620
1621 // Management sub-menu.
1622 tagMenuTitleTab.push("Management menu.")
1623 tagMenuEventTab.push( function(v, id, optionNumber){
1624 if(v==true) {
1625 menuManagementTags
1626 .css("top",menuTags.position()["top"]+200)
1627 .css("left",$('.managementTagMenuButtonIcon').position()["left"]+menuTags.position()["left"])
1628 .css("visibility", "visible");
1629 $('#'+id+'option'+optionNumber).removeClass('managementTagMenuButtonIcon').addClass('closeManagementTagMenuButtonIcon');
1630 } else {
1631 me.tagManagementMenu.closeAllOptions();
1632 menuManagementTags.css("visibility", "hidden");
1633 $('#'+id+'option'+optionNumber).removeClass('closeManagementTagMenuButtonIcon').addClass('managementTagMenuButtonIcon');
1634 }
1635 });
1636 tagMenuIconClassAttributesTab.push("managementTagMenuButtonIcon");
1637 tagMenuShareEvent.push(true);
1638
1639 // Add new tag
1640 tagManagementMenuTitleTab.push("Add new tag")
1641 tagManagementMenuEventTab.push( function(v, id, optionNumber){
1642 if(v==true) {
1643 //console.log("adding tag");
1644
1645 var tmp = document.getElementById("add-tag");
1646 if (tmp == null) {
1647 menuTags.append("<div id=add-tag></div>");
1648 $('#add-tag').css({ //GLOBALCSS
1649 position:"relative",
1650 top : 0,
1651 //left : parseInt($(me.menu.getHtmlMenuSelector()).css('width')),
1652 left : 0,
1653 height : 100,
1654 width : parseInt($(me.tagMenu.getHtmlMenuSelector()).css('width')),
1655 backgroundColor : "black",
1656 fontSize : 50,
1657 color : "white"
1658 });
1659 $('#add-tag').append("<label for=new-tag>Add Tag : </label>").append("<input id=new-tag type=text placeholder='New tag ?'>");
1660 $('#new-tag').css({//GLOBALCSS
1661 position : "relative",
1662 top : 10,
1663 //left : parseInt($(me.menu.getHtmlMenuSelector()).css('width')),
1664 left : 0,
1665 zIndex : 131,
1666 height : 80,
1667 width : parseInt($(me.tagMenu.getHtmlMenuSelector()).css('width')),
1668 fontSize : 70
1669 });
1670 $('#new-tag').autocomplete({
1671 source: suggestion_list
1672 });
1673 } else {
1674 $('#add-tag').show();
1675 $('#new-tag').show();
1676
1677 }
1678 var left_ = parseInt($(me.menu.getHtmlMenuSelector()).css("width"));
1679 var width_= parseInt($('header').css('width')) - left_ -600 /*- parseInt($('body').prop("scrollwidth"))*/; // 600 is for the three buttons on the right
1680
1681 $('#add-tag').off("tap focusin click").on("tap focusin click",
1682 function(){
1683 $('.tag').off("click");
1684
1685 $('#add-tag').off("keypress").on({
1686 keypress : function(e){
1687 if (e.which == 13 ) {
1688 if ( $('#new-tag').val().trim()!='') { // ENTER
1689 var tmpNewTag = $('#new-tag').val().trim();// .trim() to avoid whitespace or encoding problems
1690 tmpNewTag = newTag_conformance(tmpNewTag);
1691 if ($.inArray(tmpNewTag, globalTagsList) == -1) { // Check if the new tag is not already stored as tag
1692 console.log("add New Tag ", tmpNewTag);
1693 emit_newTag("add-tag",tmpNewTag);
1694
1695 } else {
1696 console.log("Tag already exists!");
1697 $('#tag-notif').text("This tag already exists!");
1698 }
1699 $('#new-tag').val("");
1700 //console.log("exitting add button");
1701 }
1702 $('#menu'+id+">#option"+optionNumber).click();
1703 }
1704 }
1705 });
1706 }
1707 );
1708 $('#add-tag').off("autocompleteselect").on("autocompleteselect", function(event, ui) {
1709 document.getElementById("new-tag").value = ui.item.value;
1710 var myEvent = jQuery.Event("keypress");
1711 myEvent.which = 13;
1712 myEvent.keyCode = 13;
1713 $('#add-tag').trigger(myEvent);
1714 $('#new-tag').value = ""; // This line
1715 return false; // *and* this line: to clean the field for the next use!
1716
1717 });
1718
1719
1720 $('#'+id+'option'+optionNumber).removeClass('addTagButtonIcon').addClass('closeAddTagButtonIcon');
1721 } else {
1722 //console.log("end adding tag");
1723 $('#add-tag').hide();
1724 $('#new-tag').hide();
1725 $('#'+id+'option'+optionNumber).removeClass("closeAddTagButtonIcon").addClass("addTagButtonIcon");
1726 }
1727 });
1728
1729 tagManagementMenuIconClassAttributesTab.push("addTagButtonIcon");
1730 tagManagementMenuShareEvent.push(false);
1731
1732 // Remove tag
1733 tagManagementMenuTitleTab.push("Remove tag")
1734 tagManagementMenuEventTab.push( function(v, id, optionNumber){
1735 if(v==true) {
1736 //console.log("removing tag");
1737 $('#'+id+'option'+optionNumber).removeClass("removeTagButtonIcon").addClass("closeRemoveTagButtonIcon");
1738 me.setRemovingTag(true);
1739 } else {
1740 //console.log("end removing tag");
1741 $('#'+id+'option'+optionNumber).removeClass("closeRemoveTagButtonIcon").addClass("removeTagButtonIcon");
1742 me.setRemovingTag(false);
1743 }
1744 });
1745 tagManagementMenuIconClassAttributesTab.push("removeTagButtonIcon");
1746 tagManagementMenuShareEvent.push(true);
1747
1748 // Brush icon : to erase the tags all at once (is also triggered to clean legend and stickers when exitting tag mode)
1749 tagManagementMenuTitleTab.push("Erase all the tags")
1750 tagManagementMenuEventTab.push( function(v,id, optionNumber){
1751 //console.log("erasing tags");
1752 var buffer=0;
1753 //$('header')
1754 $("#tag-legend").prepend('<div id="validateDelTags" height="10%" width="20%" style="z-index: 100; color: yellow; font-size: 50"><h1>Are you sure you want to suppress all tags ?</h1></div>')
1755 // $('#validateDelTags').css({
1756
1757 // ,
1758 // })
1759 $('#validateDelTags').append('<button id="validButtonYes" name="validButtonYes" class="validateDelTags btn btn-info" >Yes</button>');
1760 $('#validateDelTags').append('&nbsp;&nbsp;');
1761 $('#validateDelTags').append('<button id="validButtonNo" name="validButtonNo" class="validateDelTags btn btn-info" >No</button>');
1762 $('#validButtonYes').off("click").on({
1763 // Delete all tools created on magnifyingGlass and zoomAndDrawOnNodes
1764 click : function() {
1765 if (emit_click("validateDelTags","validButtonYes"))
1766 return
1767 while(globalTagsList.length>0) {
1768 delete globalTagsColors[globalTagsList[globalTagsList.length-1]];
1769 buffer=globalTagsList.pop();
1770
1771 for(O in nodesById) {
1772 nodesById[O].removeElementFromNodeTagList(buffer);
1773 }
1774 }
1775 $('#tag-legend').children().remove();
1776 for (O in nodesByLoc)
1777 if (nodesByLoc[O].getNodeInViewportStatus()) {
1778 $('#node'+O).css({
1779 opacity : 1
1780 });
1781 }
1782 $('#validateDelTags').remove()
1783 //console.log("end erasing tags");
1784 }})
1785 $('#validButtonNo').off("click").on({
1786 click : function() {
1787 if (emit_click("validateDelTags","validButtonNo"))
1788 return
1789 $('#validateDelTags').remove()
1790 }})
1791 });
1792 tagManagementMenuIconClassAttributesTab.push("brushButtonIcon");
1793 tagManagementMenuShareEvent.push(true);
1794
1795 // Choose stickers color
1796 tagManagementMenuTitleTab.push("Choose stickers color")
1797 tagManagementMenuEventTab.push( function(v, id, optionNumber){
1798 if(v) {
1799 var defaultColor = colourNameToHex(configBehaviour.draw.defaultColor);
1800 $('#menu'+id).append('<div id=color-picker-zone style="position: absolute; top: 200px; left: 1100px"></div>');
1801 $('#color-picker-zone').append('<label for="colorChoose" style="height: 200px; width: 400px; color: white; font-size: 4em">Color:</label>');
1802 $('#color-picker-zone').append('<input type="color" value="'+defaultColor+'" id="colorChoose" style="height: 200px; width: 200px; font-size: 2em">');
1803 PaletteNodeTagFlag=true;
1804 $('#'+id+'option'+optionNumber).removeClass('paletteButtonIcon').addClass('closePaletteButtonIcon');
1805 } else {
1806 $('#color-picker-zone').remove();
1807 PaletteNodeTagFlag=false;
1808 $('#'+id+'option'+optionNumber).removeClass('closePaletteButtonIcon').addClass('paletteButtonIcon');
1809 }
1810 });
1811 tagManagementMenuIconClassAttributesTab.push("paletteButtonIcon");
1812 tagManagementMenuShareEvent.push(false);
1813
1814
1815 // Action menu
1816
1817 var actionGlobalMenuTitleTab = new Array();
1818 var actionGlobalMenuEventTab = new Array();
1819 var actionGlobalMenuIconClassAttributesTab = new Array();
1820 var actionGlobalMenuShareEvent = new Array();
1821
1822 for ( var TS in json_actions) {
1823 for ( var thisAction in json_actions[TS]) {
1824 var FuncName=json_actions[TS][thisAction][0];
1825 var IconName=json_actions[TS][thisAction][1];
1826 actionGlobalMenuTitleTab.push(TS+"_"+FuncName);
1827 actionGlobalMenuEventTab.push( (function() {
1828 var TS_=TS;
1829 var thisAction_=thisAction;
1830 return function( v, id, optionNumber){
1831 idAction = parseInt(thisAction_.replace("action",""));
1832
1833 var selections = [];
1834 var listSelectionTiles=me.getNodesToZoom();
1835 for(O in listSelectionTiles) {
1836 // Only selection for the right tag
1837 if (listSelectionTiles[O].getJsonData().tags.filter(x=>x==TS_).length)
1838 selections.push(parseInt(listSelectionTiles[O].getJsonData().variable.replace("ID-",""))-1);
1839 }
1840 if (selections.length == 0)
1841 selections=","
1842 else
1843 selections=selections.toString()
1844 addBlink($('#'+id+"option"+optionNumber));
1845 cdata={"room":my_session,"id":id,"TileSet":TS_,"action":thisAction_,"selections":selections};
1846 socket.emit("action_click", cdata, callback=function(sdata){
1847 console.log("socket send action_click ", cdata);
1848 });
1849 }
1850 })() );
1851 actionGlobalMenuIconClassAttributesTab.push(TS+"_"+IconName+"ButtonIcon");
1852 actionGlobalMenuShareEvent.push(false);
1853 }
1854 }
1855
1864
1865 var drawMenuTitleTab = new Array();
1866 var drawMenuEventTab = new Array();
1867 var drawMenuIconClassAttributesTab = new Array();
1868 var drawMenuShareEvent = new Array();
1869
1870 // Choose drawing color
1871 drawMenuTitleTab.push("Choose drawing color")
1872 drawMenuEventTab.push( function(v, id, optionNumber){
1873 if(v) {
1874 var defaultColor = colourNameToHex(configBehaviour.draw.defaultColor);
1875 $('#menu'+id).append('<div id=color-picker-zone style="position: absolute; top: 0px; left: 1100px"></div>');
1876 $('#color-picker-zone').append('<label for="colorChoose" style="height: 200px; width: 400px; color: white; font-size: 4em">Color:</label>');
1877 $('#color-picker-zone').append('<input type="color" value="'+defaultColor+'" id="colorChoose" style="height: 200px; width: 200px; font-size: 2em">');
1878 var colorChoose;
1879 colorChoose = document.querySelector("#colorChoose");
1880 colorChoose.value = defaultColor;
1881 colorChoose.addEventListener("input", updateFirst, false);
1882 colorChoose.addEventListener("change", updateAll, false);
1883 colorChoose.select();
1884
1885 drawingColor = defaultColor;
1886
1887 function updateFirst(event) {
1888 drawingColor = event.target.value;
1889 }
1890 function updateAll(event) {
1891 drawingColor = event.target.value;
1892 }
1893
1894 $('#'+id+'option'+optionNumber).removeClass('paletteButtonIcon').addClass('closePaletteButtonIcon');
1895 } else {
1896 $('#color-picker-zone').remove();
1897 $('#'+id+'option'+optionNumber).removeClass('closePaletteButtonIcon').addClass('paletteButtonIcon');
1898 }
1899 });
1900 drawMenuIconClassAttributesTab.push("paletteButtonIcon");
1901 drawMenuShareEvent.push(false);
1902
1903 // Choose line width !
1904 drawMenuTitleTab.push("Choose line width !")
1905 drawMenuEventTab.push( function(v, id, optionNumber){
1906 if(v) {
1907 //console.log("choose style");
1908 $('#menu'+id).append("<input name=lineWidthSelector id=lineWidthSelector min=0 type=number>");
1909 $('#lineWidthSelector').css({
1910 position : "absolute",
1911 top : parseInt($('#'+id+'option'+optionNumber).css("height")),
1912 left : parseInt($('#'+id+'option'+optionNumber).css("left")),
1913 width : parseInt($('#'+id+'option'+optionNumber).css("width")),
1914 });
1915 $('#lineWidthSelector').val(configBehaviour.draw.width);
1916
1917 var changeLineWidth = function(){
1918 configBehaviour.draw.width = $('#lineWidthSelector').val();
1919 //console.log("new line width value : ", configBehaviour.draw.width);
1920 };
1921
1922 $('#lineWidthSelector').off("change").on({
1923 change : changeLineWidth
1924 });
1925
1926 $('#'+id+'option'+optionNumber).removeClass('lineWidthButtonIcon').addClass('closeLineWidthButtonIcon');
1927 } else {
1928 //console.log("end choose style");
1929 $('#lineWidthSelector').remove();
1930 $('#'+id+'option'+optionNumber).removeClass("closeLineWidthButtonIcon").addClass("lineWidthButtonIcon");
1931 }
1932 });
1933 drawMenuIconClassAttributesTab.push("lineWidthButtonIcon");
1934 drawMenuShareEvent.push(false);
1935
1936 // Brush icon : to erase the drawing
1937 drawMenuTitleTab.push("Brush icon : to erase the drawing")
1938 drawMenuEventTab.push( function(v,id, optionNumber){
1939 context.clearRect(0, 0, context.canvas.width, context.canvas.height);
1940 clickX = new Array();
1941 clickY = new Array();
1942 clickDrag = new Array();
1943 p=0;
1944 });
1945 drawMenuIconClassAttributesTab.push("brushButtonIcon");
1946 drawMenuShareEvent.push(false);
1947
1948 // Save drawing
1949 drawMenuTitleTab.push("Save drawing")
1950 drawMenuEventTab.push( function(v,id, optionNumber){
1951 var canvasName = $('#zoomSupport').find(".drawing").filter(":visible").attr("id");
1952 var srcImage = $('#iframe' + canvasName.replace(/\D/g, "")).attr("src").replace(".png", "").replace(/^.*[\\\/]/, "");
1953 document.getElementById(canvasName).toBlob( function(blob) {
1954 saveAs(blob, "drawing_"+ srcImage +".png");
1955 });
1956 });
1957 drawMenuIconClassAttributesTab.push("saveButtonIcon");
1958 drawMenuShareEvent.push(false);
1959
1960 var DrawBlobs = new Map(); // maps blob IDs to drawing objects
1961
1962 var getBlob = function (canvasName) {
1963 var deferred = Q.defer();
1964
1965 var canvas = document.getElementById(canvasName);
1966 if ( $("#DrawSupport").length == 0)
1967 $("body").append('<div id="DrawSupport" style="width: '+canvas.width+'px; height: '+canvas.height+'px"></div>');
1968
1969 canvas.toBlob( function(blob) {
1970 // var canvasName = $('#zoomSupport').find(".drawing").filter(":visible").attr("id");
1971 var nodeId=canvasName.replace(/drawCanvas/g, "");
1972
1973 var thisDrawBlob=DrawBlobs.get(nodeId);
1974 if ( thisDrawBlob ) {
1975 var newImg = thisDrawBlob.image;
1976 $('#'+newImg.id).remove();
1977 var OldUrl = thisDrawBlob.url;
1978
1979 // no longer need to read the blob so it's revoked
1980 window.URL.revokeObjectURL(OldUrl);
1981
1982 // New blob
1983 var BlobUrl = window.URL.createObjectURL(blob);
1984 newImg.src = BlobUrl;
1985 $('#DrawSupport').append(newImg);
1986 thisDrawBlob.url = BlobUrl;
1987 thisDrawBlob.dataurl = canvas.toDataURL();
1988 $('#'+newImg.id).show();
1989 } else {
1990 var newImg = document.createElement('img');
1991 BlobUrl = window.URL.createObjectURL(blob);
1992
1993 newImg.id=canvasName+'_img';
1994 newImg.src = BlobUrl;
1995 $('#DrawSupport').append(newImg);
1996
1997 DrawBlobs.set(nodeId,{
1998 url: BlobUrl,
1999 dataurl: canvas.toDataURL(),
2000 nodeId: parseInt(nodeId),
2001 image: newImg,
2002 canvasName: canvasName,
2003 listNodeImg: []
2004 });
2005 }
2006 thisDrawBlob=DrawBlobs.get(nodeId);
2007 deferred.resolve(thisDrawBlob);
2008 },'image/png');
2009
2010 return deferred.promise;
2011 }
2012
2013 var DrawNodeFun = function(nodeId,Id) {
2014 var Id=parseInt(Id);
2015 var LocImg="";
2016
2017 var thisDrawBlob=DrawBlobs.get(nodeId);
2018 var canvasName=thisDrawBlob.canvasName;
2019
2020 var DrawNodeId=canvasName+"_img_"+Id;
2021 if (thisDrawBlob.listNodeImg.indexOf(Id) > -1) {
2022 $("#"+DrawNodeId).remove();
2023
2024 } else {
2025 thisDrawBlob.listNodeImg.push(Id);
2026 }
2027 LocImg=$("#"+canvasName+"_img").clone().attr('id', DrawNodeId).appendTo($("#"+Id));
2028 LocImg.css({
2029 position: "absolute",
2030 top: 0,
2031 left: 0,
2032 height: $('#'+canvasName+'_img').css('height'),
2033 width: $('#'+canvasName+'_img').css('width'),
2034 });
2035
2036 var scaleX=(spread.X/ $('#'+canvasName+'_img').css('width').replace('px',''));
2037 var scaleY=(spread.Y/ $('#'+canvasName+'_img').css('height').replace('px',''));
2038
2039 LocImg.css({'-webkit-transform': "scale("+scaleX+","+ scaleY +")",
2040 '-webkit-transform-origin': '0 0',
2041 '-moz-transform': "scale("+scaleX+","+ scaleY +")",
2042 '-moz-transform-origin': '0 0',
2043 '-o-transform': "scale("+scaleX+","+ scaleY +")",
2044 '-o-transform-origin': '0 0',
2045 '-ms-transform': "scale("+scaleX+","+ scaleY +")",
2046 'transform': "scale("+scaleX+","+ scaleY +")",
2047 'transform-origin': "0 0 0"});
2048 }
2049
2050 var chunk_size=1024*64;
2051 var send_draw_data = function(data,nodeId,canvasName,offset,offsetEnd) {
2052 var datasend=data.slice(offset,offsetEnd+1).toString();
2053
2054 var cdata={}
2055 cdata["room"]=my_session;
2056 cdata["nodeId"]=nodeId;
2057 cdata["offset"]=offset;
2058 cdata["offsetEnd"]=offsetEnd;
2059 cdata["data"]=datasend;
2060 socket.emit("uploadDraw", cdata, callback=function(sdata){
2061 //console.log("socket send draw part of "+canvasName+" from "+cdata.offset+" to "+cdata.offsetEnd);
2062 });
2063 }
2064
2065 var send_DrawBlob = function(thisDrawBlob, canvasName, nodeId, allNodes) {
2066 var canvas = document.getElementById(canvasName);
2067 var ImageData=thisDrawBlob.dataurl;
2068 var lengthData=ImageData.length;
2069 var cdata={};
2070 var nbsend = parseInt(lengthData / chunk_size) + 1;
2071 cdata["room"]=my_session;
2072 cdata["nodeId"]=nodeId;
2073 cdata["canvasName"]=canvasName;
2074 cdata["length"]=lengthData;
2075 cdata["nbsend"]=nbsend;
2076 cdata["width"]=canvas.width;
2077 cdata["height"]=canvas.height;
2078 if (typeof allNodes == 'undefined') {
2079 // emit Draw to all other clients of the session
2080 socket.emit("drawBlob", cdata, callback=function(sdata){
2081 console.log("socket send draw blob ", cdata);
2082 });
2083 } else {
2084 // emit Draw to all other clients of the session
2085 cdata["allNodes"]="true";
2086 socket.emit("drawBlob", cdata, callback=function(sdata){
2087 console.log("socket send all clients draw blob ", cdata);
2088 })
2089 }
2090 // Add progress bar
2091 // $('#buttonUnzoom').append('<div id="ProgressStatusZoom" class="progress-status"></div>')
2092 // $('#ProgressStatusZoom').append('<div id="myprogressBarZoom" class="progressBar" style="width: 0px"></div>')
2093 // $("#ProgressStatusZoom").show();
2094 // var sendProgress=0;
2095 // var updateProgressBarZoom = function() {
2096 // if (sendProgress>=100) clearInterval(idProgress);
2097 // $("#myprogressBarZoom").css({width: sendProgress+"%"});
2098 // // $("myprogressBarZoom").html(sendProgress + '%');
2099 // };
2100 // var idProgress=setInterval(updateProgressBarZoom,1);
2101
2102 for( var i=0; i<nbsend; i++ ) {
2103 var offset=i*chunk_size;
2104 var offsetEnd=Math.min(offset-1+chunk_size,lengthData-1)
2105 send_draw_data(ImageData,nodeId,canvasName,offset,offsetEnd);
2106 // sendProgress=parseInt((i+1)*100/nbsend);
2107 // updateProgressBarZoom();
2108 }
2109 //$("#ProgressStatusZoom").remove();
2110 return nbsend
2111 }
2112
2113 // Node drawing
2114 drawMenuTitleTab.push("Node drawing")
2115 drawMenuEventTab.push( function(v,id, optionNumber){
2116 var canvasName = $('#zoomSupport').find(".drawing").filter(":visible").attr("id");
2117 var nodeId=canvasName.replace(/drawCanvas/g, "");
2118 var thisDrawBlob=[];
2119
2120 getBlob(canvasName).then(function(thisDrawBlob) {
2121
2122 try {
2123 nbsend=send_DrawBlob(thisDrawBlob, canvasName, nodeId)
2124 } catch(err) {
2125 console.log("Error : init send draw "+err.toString())
2126 }
2127 return thisDrawBlob
2128 }).then(function(thisDrawBlob) {
2129 var newImg = thisDrawBlob.image;
2130 console.log("blob",thisDrawBlob);
2131
2132 newImg.onload = function() {
2133
2134 DrawNodeFun(nodeId,nodeId);
2135 $('#'+this.id).hide();
2136 };
2137
2138 $('#buttonUnzoom').click();
2139 return thisDrawBlob
2140 });
2141 });
2142 drawMenuIconClassAttributesTab.push("DrawOnNodeButtonIcon");
2143 drawMenuShareEvent.push(false);
2144
2145
2146 // Duplicate draw on other nodes
2147 drawMenuTitleTab.push("Duplicate draw on other nodes")
2148 drawMenuEventTab.push( function(v,id, optionNumber){
2149 var canvasName = $('#zoomSupport').find(".drawing").filter(":visible").attr("id");
2150 var nodeId=canvasName.replace(/drawCanvas/g, "");
2151
2152 getBlob(canvasName).then(function(thisDrawBlob) {
2153 try {
2154 nbsend=send_DrawBlob(thisDrawBlob, canvasName, nodeId, true)
2155 } catch(err) {
2156 console.log("Error : init send draw "+err.toString())
2157 }
2158 return thisDrawBlob
2159 }).then(function(thisDrawBlob) {
2160
2161 var newImg = thisDrawBlob.image;
2162 console.log("blob",thisDrawBlob);
2163
2164 newImg.onload = function() {
2165
2166 for(O in nodesByLoc) {
2167 DrawNodeFun(nodeId,O);
2168 }
2169
2170 $('#'+this.id).hide();
2171 };
2172
2173 $('#buttonUnzoom').click();
2174 return thisDrawBlob
2175 });
2176 });
2177 drawMenuIconClassAttributesTab.push("DrawOnAllNodesIcon");
2178 drawMenuShareEvent.push(false);
2179
2180 // Share draws
2181 socket.on('receive_draw_img', function(sdatai){
2182 console.log("receive_draw_img",sdatai);
2183
2184 var canvasName = sdatai.canvasName;
2185 var nodeId = sdatai.nodeId;
2186 var offset=0;
2187 var offsetend=0;
2188 $("#notifications").html("")
2189 $("#notifications").append('<div id="ProgressStatusUpload" class="progress-status">'+
2190 '<div id="myprogressBarUp" class="progressBar" style="width: 0px"></div></div>')
2191 $("#ProgressStatusUpload").show();
2192
2193 var sendProgress=0;
2194 var update_progressBarUp = function() {
2195 if (sendProgress>100) clearInterval(idProgress);
2196 $("#myprogressBarUp").css({width: sendProgress+"%"});
2197 $("#myprogressBarUp").html(sendProgress + '%');
2198 };
2199 var idProgress=setInterval(update_progressBarUp,10);
2200
2201 if ( $("#DrawSupport").length == 0)
2202 $("body").append('<div id="DrawSupport" style="width: '+sdatai.width+'px; height: '+sdatai.height+'px"></div>');
2203
2204 var data="";
2205 socket.off('receive_draw_part').on('receive_draw_part', function(sdatap){
2206
2207 // $("#DrawSupport").show();
2208 // $(".node").hide();
2209 // TODO Verify the right origin of the data ? nodeId + canvasName ?
2210
2211 receivedata=sdatap.data;
2212 if (offset == 0) {
2213 data=receivedata;
2214 } else {
2215 data=data+receivedata;
2216 }
2217 offset=parseInt(sdatap.offset);
2218 offsetend=parseInt(sdatap.offsetEnd);
2219 datalength=data.length;
2220
2221 sendProgress=parseInt((offsetend+1)*100/sdatai.length);
2222
2223 if (offsetend == sdatai.length-1) {
2224 socket.off('receive_draw_part');
2225
2226 sendProgress=101;
2227
2228 if ( $('#'+canvasName+'_img').length == 0 )
2229 $("#DrawSupport").append('<img id="'+canvasName+'_img" src=""'+
2230 ' width='+sdatai.width+' height='+sdatai.height+'></img>')
2231 var newImg=$("#"+canvasName+"_img")[0];
2232 var thisDrawBlob=DrawBlobs.get(nodeId);
2233
2234 if ( thisDrawBlob ) {
2235 newImg = thisDrawBlob.image;
2236 $("#"+newImg.id).remove();
2237 var OldUrl = thisDrawBlob.url;
2238
2239 // no longer need to read the blob so it's revoked
2240 window.URL.revokeObjectURL(OldUrl);
2241
2242 newImg.src = data;
2243 $("#DrawSupport").append(newImg);
2244
2245 $('#'+newImg.id).show();
2246 } else {
2247 newImg.src = data;
2248
2249 DrawBlobs.set(nodeId,{
2250 url: "",
2251 dataurl: newImg.src,
2252 nodeId: parseInt(nodeId),
2253 image: newImg,
2254 canvasName: canvasName,
2255 listNodeImg: []
2256 });
2257 }
2258
2259 if ( $('#'+canvasName).length > 0 ) {
2260 var canvas = document.getElementById(canvasName);
2261 var ctx = canvas.getContext('2d');
2262 ctx.drawImage(newImg, 0, 0);
2263 }
2264
2265 newImg.onload = function() {
2266 if (sdatai.allNodes) {
2267 for(O in nodesByLoc) {
2268 DrawNodeFun(nodeId,O);
2269 }
2270 } else {
2271 DrawNodeFun(nodeId,nodeId);
2272 }
2273 }
2274 // $("#DrawSupport").hide();
2275 // $(".node").show();
2276
2277 $("#ProgressStatusUpload").remove();
2278 }
2279 offset=parseInt(sdatap.offsetEnd);
2280 });
2281 });
2282
2283 // Close
2284
2291
2292 var MSMenuTitleTab = new Array();
2293 var MSMenuEventTab = new Array();
2294 var MSMenuIconClassAttributesTab = new Array();
2295 var MSMenuShareEvent = new Array();
2296
2303
2304 // Apply MS on selection
2305 MSMenuTitleTab.push("Apply MS on selection")
2306 MSMenuEventTab.push( function( id, optionNumber){
2307 // Zoomed div and Handlered div over it
2308 var handleMaster,Handled;
2309 // iframe of the Handled
2310 var iframeHandled;
2311 // number of the master
2312 var iHandled;
2313
2314 // Variables for magnifyingGlass
2315 var nodeMSTab = me.getNodesToZoom();
2316 var ratio =spread.Y/spread.X;
2317 var initSpread = spread;
2318
2319 if(nodeMSTab.length>0) {
2320 menuMS.css("visibility", "hidden");
2321
2322 // We repeat first node because its div will be used as master.
2323 nodeMSTab=Array(nodeMSTab[0]).concat(nodeMSTab);
2324 if (parseBool(configBehaviour.onlyMasterMS))
2325 configBehaviour.allMSShowMax=0;
2326 if (nodeMSTab.length > configBehaviour.allMSShowMax+1) {
2327 nodeMSTab_=nodeMSTab.slice(0, configBehaviour.allMSShowMax+1);
2328 me.magnifyingGlass(nodeMSTab_,ratio,initSpread);
2329 } else {
2330 me.magnifyingGlass(nodeMSTab,ratio,initSpread);
2331 }
2332
2333 // We begin with first selected as Master
2334 handleMaster=$("#Zoomed"+0);
2335
2336 // We create the listened div
2337 $("#zoomSupport").append('<div id=Handled class=handled></div>');
2338
2339 iframeHandled=handleMaster.children("iframe");
2340 handleMaster.children(".info").html("MASTER Tile");
2341 handleMaster.children(".stickers_zone").remove()
2342
2343 urlMaster=nodeMSTab[0].getJsonData().url;
2344 urlMasterPath=urlMaster.slice(0,urlMaster.search("vnc.html"));
2345
2346 // We set the property of the iframe
2347 var HandledJQ=$("#Handled");
2348 HandledJQ.css({
2349 height : iframeHandled.css('height'),
2350 width : iframeHandled.css('width'),
2351 });
2352
2353 // DOM path to this handled div
2354 Handled=$("#zoomSupport").children(".handled")[0];
2355
2356 $('header').append("<div id=explain-StartMS>First node is duplicated to have the master to interact.</div>");
2357 $('#explain-StartMS').css({
2358 position : "fixed",
2359 backgroundColor : "green",
2360 color : "black",
2361 fontSize : 100,
2362 left : "15%",
2363 top : 0 ,
2364 zIndex : 121
2365 });
2366
2367 // Start Master-Slave function
2368 function initMSList() {
2369 // This function will work only for VNC connections
2370 try {
2371 str_autoconnect="?autoconnect=1&"
2372 MSPath=urlMasterPath+"vnc_multi.html"+str_autoconnect+"NbRFB="+(nodeMSTab.length-1)+"&";
2373 for(i=1;i<nodeMSTab.length;i++) {
2374 var urlNode=nodeMSTab[i].getJsonData().url;
2375 urlNodeParam=urlNode.slice(urlNode.search("vnc.html")+"vnc.html".length+str_autoconnect.length);
2376 NodeParams=urlNodeParam.split('&');
2377 for (P in NodeParams) {
2378 thisparam=NodeParams[P].slice(0,NodeParams[P].search("="));
2379 switch(thisparam) {
2380 case("host"):
2381 case("port"):
2382 case("password"):
2383 case("path"):
2384 case("token"):
2385 case("encrypt"):
2386 NodeParams[P]=NodeParams[P].replace("=",(i-1)+"=");
2387 case("autoconnect"):
2388 case("true_color"):
2389 // suppress param
2390 }
2391 }
2392 MSPath=MSPath+NodeParams.join('&')+'&';
2393 }
2394 iframeHandled.attr("src",MSPath+"&true_color=1");
2395 } catch(e) {
2396 console.log("Master-Slave function will work only for VNC connections.");
2397 }
2398 }
2399
2400
2401 // Start Master-Slave
2402 initMSList();
2403
2404 // unZoom function
2405 $('#buttonUnzoom').on({
2406 click : function(){
2407 $('#explain-StartMS').remove();
2408
2409 try {
2410 var Handled=$("#zoomSupport").children(".handled")[0];
2411 Handled.remove();
2412 } catch (err) {
2413 }
2414 menuMS.css("visibility", "visible");
2415
2416 // for(O in nodesById) {
2417 // me.removeNodeToZoom(O);
2418 // }
2419 // me.setZoomSelection(true);
2420 }
2421 });
2422 }
2423 });
2424 MSMenuIconClassAttributesTab.push("expandZoomButtonIcon");
2425 MSMenuShareEvent.push(false);
2426
2427 // Apply MS on all tiles
2428 MSMenuTitleTab.push("Apply MS on all tiles")
2429 MSMenuEventTab.push( function(v, id, optionNumber){
2430 me.resetNodesToZoom();
2431 var nodeMSTab = me.getNodesToZoom();
2432
2433 for(O in nodesById) {
2434 nodeMSTab.push(nodesById[O]);
2435 }
2436 menuMS.children("[class*=expandZoomButtonIcon]").click();
2437
2438 for(O in nodesById) {
2439 me.removeNodeToZoom(O);
2440 }
2441 me.setZoomSelection(true);
2442
2443 });
2444 MSMenuIconClassAttributesTab.push("AllMSButtonIcon");
2445 MSMenuShareEvent.push(false);
2446
2447 // explain MS
2448 MSMenuTitleTab.push("Master-Slave explain area")
2449 MSMenuEventTab.push( function(v, id, optionNumber){
2450 });
2451 MSMenuIconClassAttributesTab.push("explain-MS");
2452 MSMenuShareEvent.push(false);
2453
2460
2463 var ListZoomFunctions=["zoomNodes","zoom","MS","draw"];
2464 this.disableOtherZoom = function (myzoomfunction) {
2465 for (var otherZoom in ListZoomFunctions) {
2466 var thisZoom=ListZoomFunctions[otherZoom];
2467 if ( thisZoom != myzoomfunction )
2468 var thiszoom=thisZoom[0].toUpperCase()+thisZoom.substring(1);
2469 if ($(".close"+thisZoom+"ButtonIcon")[0]) {
2470 $(".close"+thisZoom+"ButtonIcon").click();
2471 } else if ($(".close"+thiszoom+"ButtonIcon")[0]) {
2472 $(".close"+thiszoom+"ButtonIcon").click();
2473 }
2474 }
2475 };
2476
2479 this.enableOtherZoom = function (myzoomfunction) {
2480 // for (var otherZoom in ListZoomFunctions) {
2481 // var thisZoom=ListZoomFunctions[otherZoom];
2482 // if ( thisZoom != myzoomfunction )
2483 // $(".disable"+thisZoom+"ButtonIcon").removeClass("disable"+thisZoom+"ButtonIcon").addClass(thisZoom+"ButtonIcon");
2484 // }
2485 };
2486
2491
2492 var zoomMenuTitleTab = new Array();
2493 var zoomMenuEventTab = new Array();
2494 var zoomMenuIconClassAttributesTab = new Array();
2495 var zoomMenuShareEvent = new Array();
2496
2497 // Apply Zoom button
2498 zoomMenuTitleTab.push("Apply zoom button")
2499 zoomMenuEventTab.push( function(v, id, optionNumber) {
2500
2501 // Variables for magnifyingGlass
2502 var nodeZoomTab = me.getNodesToZoom();
2503 var ratio =spread.Y/spread.X;
2504 var initSpread = spread;
2505
2506 if(nodeZoomTab.length>0) {
2507 $("#menu"+id).css("visibility", "hidden");
2508
2509 //$('#buttonUnzoom').hide();
2510 me.magnifyingGlass(nodeZoomTab,ratio,initSpread);
2511 // me.resetNodesToZoom();
2512
2513 // unZoom function
2514 $('#buttonUnzoom').on({
2515 click: function(){
2516
2517 //console.log("click unzoom");
2518 menuZoom.css("visibility", "visible");
2519 }
2520 });
2521
2522 }
2523 });
2524 zoomMenuIconClassAttributesTab.push("expandZoomButtonIcon");
2525 zoomMenuShareEvent.push(false);
2526
2527 zoomMenuTitleTab.push("Zoom explain area")
2528 zoomMenuEventTab.push( function(v, id, optionNumber) {
2529 });
2530
2531 zoomMenuIconClassAttributesTab.push("explain-zoom");
2532 zoomMenuShareEvent.push(false);
2533
2534
2541
2542 var zoomGlobalMenuTitleTab = new Array();
2543 var zoomGlobalMenuEventTab = new Array();
2544 var zoomGlobalMenuIconClassAttributesTab = new Array();
2545 var zoomGlobalMenuShareEvent = new Array();
2546
2547 // Zoom menu with selection
2548 zoomGlobalMenuTitleTab.push("Zoom menu with selection")
2549 zoomGlobalMenuEventTab.push( ( function(){
2550
2551 return function(v,id,optionNumber){
2552
2553 // for(O in nodesById) {
2554 // nodesById[O].updateSelectedStatus(false);
2555 // }
2556
2557 if(v==true) {
2558 //me.setZoomSelection(true); // To change the behaviour of a hitbox click, cf clickHB method // DEPRECATED ?
2559 // Deactivate other magnify menus
2560 me.disableOtherZoom("zoom")
2561 BlockDragAndDrop();
2562
2563 for (O in nodesByLoc)
2564 if (nodesByLoc[O].getNodeInViewportStatus()) {
2565 nodesByLoc[O].sub('').off();
2566 nodesByLoc[O].sub('hitbox').off("click").on("click", clickHBSelect);
2567 nodesByLoc[O].sub('hitbox').off("mouseenter");
2568 }
2569 menuZoom.children('[class*=explain-zoom]')[0].innerText="Click on the left of the nodes to select them. Green nodes will be selected.";
2570 menuZoom.children('[class*=explain-zoom]').css({
2571 backgroundColor : "green",
2572 color : "black",
2573 fontSize : 100,
2574 width: 2000,
2575 });
2576
2577 menuZoom.css("visibility", "visible");
2578 menuZoom.css("top", TagHeight+"px");
2579
2580 $('#'+id+'option'+optionNumber).removeClass('zoomButtonIcon').addClass("closezoomButtonIcon");
2581
2582 } else {
2583
2584 // Activate other magnify menus
2585 me.enableOtherZoom("zoom")
2586 EnableDragAndDrop();
2587
2588 me.setZoomSelection(false);
2589 me.resetNodesToZoom();
2590 $('#buttonUnzoom').click();
2591 //me.meshEventReStart();
2592
2593 menuZoom.css("visibility", "hidden");
2594
2595 $('#'+id+'option'+optionNumber).removeClass("closezoomButtonIcon").addClass("zoomButtonIcon");
2596 }
2597 return 0;
2598 };
2599 })());
2600
2601 zoomGlobalMenuIconClassAttributesTab.push("zoomButtonIcon");
2602 zoomGlobalMenuShareEvent.push(false);
2603
2604
2605 // MasterSlave Menu
2606 zoomGlobalMenuTitleTab.push("MasterSlave Menu")
2607 zoomGlobalMenuEventTab.push( (function(){
2608
2609 return function(v,id,optionNumber){
2610
2611 me.setZoomSelection(true);
2612
2613 // for(O in nodesById) {
2614 // nodesById[O].updateSelectedStatus(false);
2615 // }
2616
2617 if(v==true) {
2618 //me.setZoomSelection(true); // To change the behaviour of a hitbox click, cf clickHB method // DEPRECATED ?
2619
2620 // Deactivate other magnify menus
2621 me.disableOtherZoom("MS")
2622 BlockDragAndDrop();
2623
2624 for (O in nodesByLoc)
2625 if (nodesByLoc[O].getNodeInViewportStatus()) {
2626 nodesByLoc[O].sub('').off();
2627 nodesByLoc[O].sub('hitbox').off("click").on("click", clickHBSelect);
2628 nodesByLoc[O].sub('hitbox').off("mouseenter");
2629 }
2630
2631 menuMS.children('[class*=explain-MS]')[0].innerText="Click on the left of the nodes to select them. Click on left \"validate button\" or right \"ALL selected\" button.";
2632 menuMS.children('[class*=explain-MS]').css({
2633 backgroundColor : "green",
2634 color : "black",
2635 fontSize : 100,
2636 width: 2800,
2637 });
2638
2639 menuMS.css("visibility", "visible");
2640 menuMS.css("top", TagHeight+"px");
2641
2642 $('#'+id+'option'+optionNumber).removeClass("MSButtonIcon").addClass("closeMSButtonIcon");
2643
2644 } else {
2645
2646 // Activate other magnify menus
2647 me.enableOtherZoom("MS")
2648 EnableDragAndDrop();
2649
2650 me.setZoomSelection(false);
2651 me.resetNodesToZoom();
2652 // We must replace iframes on their right place in the DOM !
2653 try {
2654 var Handled=$("#zoomSupport").children(".handled")[0];
2655 Handled.remove();
2656 } catch(err) {
2657 }
2658 $('#buttonUnzoom').click();
2659 //me.meshEventReStart();
2660
2661 menuMS.css("visibility", "hidden");
2662
2663 $('#'+id+'option'+optionNumber).removeClass("closeMSButtonIcon").addClass("MSButtonIcon");
2664
2665 };
2666
2667 return 0;
2668 };
2669 }) ());
2670
2671 zoomGlobalMenuIconClassAttributesTab.push("MSButtonIcon");
2672 zoomGlobalMenuShareEvent.push(false);
2673
2675 zoomGlobalMenuTitleTab.push("Show fast zoom button")
2676 zoomGlobalMenuEventTab.push( ( function(){
2677
2678 return function(v, id, optionNumber){
2679 if (v==true) {
2680 me.disableOtherZoom("zoomNodes")
2681 BlockDragAndDrop();
2682
2683 $('.zoomNodeButtonIcon').show();
2684 $('#'+id+'option'+optionNumber).removeClass('zoomNodesButtonIcon').addClass('closeZoomNodesButtonIcon');
2685 } else {
2686 // Activate other magnify menus
2687 me.enableOtherZoom("zoomNodes")
2688 EnableDragAndDrop();
2689
2690 $('.zoomNodeButtonIcon').hide();
2691 $('#'+id+'option'+optionNumber).removeClass("closeZoomNodesButtonIcon").addClass("zoomNodesButtonIcon");
2692 }
2693 };
2694
2695 })());
2696 zoomGlobalMenuIconClassAttributesTab.push("zoomNodesButtonIcon");
2697 zoomGlobalMenuShareEvent.push(false);
2698
2705
2706 // State Menu Global
2707
2708 var stateGlobalMenuTitleTab = new Array();
2709 var stateGlobalMenuEventTab = new Array();
2710 var stateGlobalMenuIconClassAttributesTab = new Array();
2711 var stateGlobalMenuShareEvent = new Array();
2712
2713 // Show OnOff button
2714 stateGlobalMenuTitleTab.push("Show OnOff button")
2715 stateGlobalMenuEventTab.push( ( function(){
2716
2717 return function(v, id, optionNumber){
2718 if (v==true) {
2719 for (O in nodesByLoc)
2720 if (nodesByLoc[O].getNodeInViewportStatus())
2721 nodesByLoc[O].getHtmlNode().children(".onoff").css({display : "inline"});
2722 $('#'+id+'option'+optionNumber).removeClass('OnOffButtonIcon').addClass('closeOnOffButtonIcon');
2723 } else {
2724 for (O in nodesByLoc)
2725 if (nodesByLoc[O].getNodeInViewportStatus())
2726 nodesByLoc[O].getHtmlNode().children(".onoff").css({display : "none"});
2727 $('#'+id+'option'+optionNumber).removeClass("closeOnOffButtonIcon").addClass("OnOffButtonIcon");
2728
2729 }
2730 };
2731
2732 })());
2733
2734 stateGlobalMenuIconClassAttributesTab.push("OnOffButtonIcon");
2735 stateGlobalMenuShareEvent.push(true);
2736
2738 stateGlobalMenuTitleTab.push("Show QR code link")
2739 stateGlobalMenuEventTab.push( ( function(){
2740
2741 return function(v, id, optionNumber){
2742 if (v==true) {
2743 $('.qrcode').show();
2744 $('#'+id+'option'+optionNumber).removeClass('QRcodeButtonIcon').addClass('closeQRcodeButtonIcon');
2745 } else {
2746 $('.qrcode').hide();
2747 $('#'+id+'option'+optionNumber).removeClass("closeQRcodeButtonIcon").addClass("QRcodeButtonIcon");
2748
2749 }
2750 };
2751
2752 })());
2753
2754 stateGlobalMenuIconClassAttributesTab.push("QRcodeButtonIcon");
2755 stateGlobalMenuShareEvent.push(true);
2756
2758 stateGlobalMenuTitleTab.push("Show node info")
2759 stateGlobalMenuEventTab.push( ( function(){
2760
2761 return function(v, id, optionNumber){
2762 if (v==true) {
2763 for (O in nodesByLoc)
2764 if (nodesByLoc[O].getNodeInViewportStatus())
2765 nodesByLoc[O].getHtmlNode().children(".info").css({visibility : "visible", display : "inline" });
2766 $('#'+id+'option'+optionNumber).removeClass('showInfoButtonIcon').addClass('closeShowInfoButtonIcon');
2767 } else {
2768 if(!! configBehaviour.alwaysShowInfo) {
2769 for (O in nodesByLoc)
2770 if (nodesByLoc[O].getNodeInViewportStatus())
2771 nodesByLoc[O].getHtmlNode().children(".info").css({visibility : "hidden"});
2772 }
2773 $('#'+id+'option'+optionNumber).removeClass("closeShowInfoButtonIcon").addClass("showInfoButtonIcon");
2774
2775 }
2776 };
2777
2778 })());
2779
2780 stateGlobalMenuIconClassAttributesTab.push("showInfoButtonIcon");
2781 stateGlobalMenuShareEvent.push(true);
2782
2791
2792 var managementGlobalMenuTitleTab = new Array();
2793 var managementGlobalMenuEventTab = new Array();
2794 var managementGlobalMenuIconClassAttributesTab = new Array();
2795 var managementGlobalMenuShareEvent = new Array();
2796
2798
2799 // Share modification of draw in Draws Management Menu.
2800 emit_ModifDraws=function(action,nodeId) {
2801 cdata={"room":my_session,"action":action,"nodeId":nodeId};
2802 socket.emit("modif_draws", cdata, callback=function(sdata){
2803 console.log("socket send modif_draws ", cdata);
2804 });
2805 }
2806
2807 socket.on('receive_SuppressDraw',function(sdata){
2808 var thisblob=DrawBlobs.get(sdata.nodeId.toString());
2809 var newImg=thisblob.image;
2810 var canvasName=thisblob.canvasName;
2811 for (ind in thisblob.listNodeImg) {
2812 Id=thisblob.listNodeImg[ind];
2813 DrawNodeId=canvasName+"_img_"+Id;
2814 $("#"+DrawNodeId).remove();
2815 }
2816 DrawBlobs.delete(thisblob.nodeId.toString());
2817 $('#'+newImg.id).remove();
2818 $('#draws'+thisblob.nodeId).remove();
2819 });
2820
2821 socket.on('receive_HideDraw',function(sdata){
2822 var thisblob=DrawBlobs.get(sdata.nodeId.toString());
2823 var canvasName=thisblob.canvasName;
2824 for (ind in thisblob.listNodeImg) {
2825 Id=thisblob.listNodeImg[ind];
2826 DrawNodeId=canvasName+"_img_"+Id;
2827 $("#"+DrawNodeId).hide();
2828 }
2829 $('input[name=drawOtherNodes'+thisblob.nodeId+']').val('yes').attr("checked",true);
2830 });
2831
2832 socket.on('receive_ShowDraw',function(sdata){
2833 var thisblob=DrawBlobs.get(sdata.nodeId.toString());
2834 var canvasName=thisblob.canvasName;
2835 for (ind in thisblob.listNodeImg) {
2836 Id=thisblob.listNodeImg[ind];
2837 DrawNodeId=canvasName+"_img_"+Id;
2838 $("#"+DrawNodeId).show();
2839 }
2840 $('input[name=drawOtherNodes'+thisblob.nodeId+']').val('no').attr("checked",false);
2841 });
2842
2843 managementGlobalMenuTitleTab.push("Draws management")
2844 managementGlobalMenuEventTab.push( ( function(){
2845
2846 return function(v, id, optionNumber){
2847 if (v==true) {
2848 $('header').append("<div id=DrawsMenu class=option-draws></div>");
2849 $('#DrawsMenu').css({
2850 backgroundColor : "SkyBlue",
2851 color : "black",
2852 fontSize : 50,
2853 left: 500,
2854 width: 1000,
2855 zIndex: 801
2856 });
2857 // maps blob IDs to drawing objects
2858 DrawBlobs.forEach(function(thisblob) {
2859 $('#DrawsMenu').append("<div id='draws"+thisblob.nodeId+"'> </div>");
2860 $('#draws'+thisblob.nodeId).append("<input type='checkbox' id='drawNode"+thisblob.nodeId+"' name='drawNode"+thisblob.nodeId+"' value='no'> supress Node "+thisblob.nodeId+" | </input>");
2861 $('#draws'+thisblob.nodeId).append("<input type='checkbox' id='drawOtherNodes"+thisblob.nodeId+"' name='drawOtherNodes"+thisblob.nodeId+"' value='no'> Hide all clone "+ thisblob.listNodeImg.length+"</br></input>");
2862 //$('input[name=drawNode'+thisblob.nodeId+'][value=yes]').attr("checked", true);
2863 $('#drawNode'+thisblob.nodeId).off("change").on({
2864 change : function() {
2865 // Checked : delete the blob and all pictures on tiles.
2866 emit_ModifDraws("SuppressDraw",thisblob.nodeId);
2867 window.URL.revokeObjectURL(thisblob.url);
2868 }
2869 });
2870 //$('input[name=drawOtherNodes'+thisblob.nodeId+'][value=yes]').attr("checked", true);
2871 $('#drawOtherNodes'+thisblob.nodeId).off("change").on({
2872 change : function() {
2873 if (!! $('input[name=drawOtherNodes'+thisblob.nodeId+']').attr("checked")) {
2874 // Checked : Hide all pictures of this blob on tiles.
2875 emit_ModifDraws("HideDraw",thisblob.nodeId);
2876 } else {
2877 // unChecked : Show all pictures of this blob on tiles.
2878 emit_ModifDraws("ShowDraw",thisblob.nodeId);
2879 }
2880 }
2881 });
2882 });
2883 $('#'+id+'option'+optionNumber).removeClass('DrawsButtonIcon').addClass('closeDrawsButtonIcon');
2884
2885 } else {
2886 $('header').children("#DrawsMenu").remove();
2887 $('#'+id+'option'+optionNumber).removeClass("closeDrawsButtonIcon").addClass("DrawsButtonIcon");
2888 }
2889 };
2890
2891 })() );
2892
2893 managementGlobalMenuIconClassAttributesTab.push("DrawsButtonIcon");
2894 managementGlobalMenuShareEvent.push(true);
2895
2897 managementGlobalMenuTitleTab.push("Save working session")
2898 managementGlobalMenuEventTab.push( function(v,id,optionNumber){
2899 // Concatenate json data
2900 idFinalLocation=0;
2901 for(O in nodesByLoc) {
2902 var id=nodesByLoc[O].getId();
2903 if (nodesByLoc[O].getOnOffStatus()) {
2904 // Save positions
2905 nodesByLoc[O].getJsonData().IdLocation = nodesByLoc[O].getIdLocation();
2906 idFinalLocation++;
2907 // Save usernotes
2908 nodesByLoc[O].getJsonData().userNotes = nodesByLoc[O].getComment();
2909 // Save tags
2910 nodesByLoc[O].getJsonData().tags = nodesByLoc[O].getNodeTagList();
2911 }
2912 }
2913
2914 // Ask for save all tiles or just visibles ones (default)
2915 $('#notifications').html('<div id=saveTiles height="10%" width="50%"></div>');
2916 $('#saveTiles').append('<form style="font-size: 45px"> Save all tiles or just visible ones (default) ? &nbsp;&nbsp;'
2917 + '<input type="checkbox" id="allTiles" value="no" ></input>&nbsp;&nbsp;'
2918 + '<button id="submitTiles" name="submitTiles" class="btn btn-info" style="font-size: 40px"> Submit</button>&nbsp;&nbsp;'
2919 + '</form>');
2920 var saveAllTiles=false;
2921 $('#allTiles').off("change").on({
2922 change : function() {
2923 saveAllTiles=$('input[name=allTiles]').attr("checked");
2924 }
2925 });
2926 $('#submitTiles').off("click").on("click",function() {
2927 $('#saveTiles').remove();
2928
2929 // Reconstruct another nodes.js with the same structure
2930 var temp = "{\"nodes\": [XXX] }";
2931 var id=0;
2932
2933 for(O in nodesByLoc) {
2934
2935 if (saveAllTiles || nodesByLoc[O].getOnOffStatus()) {
2936 id=nodesByLoc[O].getId();
2937 //console.log(id);
2938
2939 var temp3 ="{{***}}";
2940
2941 for(W in nodesByLoc[O].getJsonData()) {
2942 if (W == "tags" ) {
2943 var ListTags=new Array();
2944 nodesByLoc[O].getNodeTagList().forEach(function(currentValue) {
2945 if (currentValue in globalFloatingTags) {
2946 var ft=nodesByLoc[O].getFloatingTag()
2947 ListTags.push("'{"+currentValue+","+ft[currentValue]["m"]+","+ft[currentValue]["val"]+","+ft[currentValue]["M"] + "}'") }
2948 else {
2949 ListTags.push("'"+currentValue + "'") }
2950 })
2951 var mytext = "\""+W+"\""+" : "+"["+ListTags.toString().replace(/\'/g,'\"')+"], {***}"
2952 } else if ( W == "comment") {
2953 // Don't save old comment because user may have modified it in postit.
2954 var mytext = "{***}";
2955 } else if ( W == "userNotes") {
2956 comment=nodesByLoc[O].getJsonData()["userNotes"].toString().replace(/\"/g,"'")
2957 var mytext = "\"comment\""+" : "+"\""+comment+"\""+", {***}"
2958 // } else if ( W == "IdLocation") {
2959 // var mytext = "\""+W+"\""+" : "+"\""+nodesByLoc[0].getIdLocation().toString()+"\""+",\n {***}";
2960 } else {
2961 var mytext = "\""+W+"\""+" : "+"\""+nodesByLoc[O].getJsonData()[W].toString().replace(/\"/g,"'").replace(/\n/g,"")+"\""+", {***}";
2962 }
2963 temp3=temp3.replace("{***}",mytext);
2964 }
2965 temp3=temp3.replace(", {***}","");
2966 temp=temp.replace("XXX",temp3+",XXX");
2967 }
2968 }
2969 // Save the file with a clear name (date and time, name of the project)
2970 temp=temp.replace(",XXX","");
2971 // tempFile = "var text_ = \n "+temp+";\nvar jsDataTab = text_.nodes;";
2972 tempFile=temp;
2973
2974 var sessionDate = new Date();
2975 var strDate=sessionDate.toLocaleDateString({day: "2-digit", month: "2-digit"}).replace(/\//g, "-") + "_" + sessionDate.toLocaleTimeString("fr-FR").replace(/:/g, "-")
2976 //var fileName = my_session + "_" + "tiles_" + strDate + ".js";
2977 //var file = new File([tempFile], fileName, {type: "text/plain;charset=utf-8"},{ autoBom: false });
2978 var fileName = my_session + "_" + "tiles_" + strDate + ".json";
2979
2980 // socket save new session ??
2981 $('#notifications').html('<div id=saveValidate height="10%" width="50%"></div>');
2982 // TODO method POST with
2983 //<form method="POST">
2984 $('#saveValidate').append('<form style="font-size: 45px"> New suffix for save '+my_session+'&nbsp;&nbsp;'
2985 + '<input type=text id="newSuffix" value="'+strDate+'" style="width:20%"></input>&nbsp;&nbsp;'
2986 + 'Change description : <input type=text id="newDescr" value="'+my_description+'" style="width:50%"></input>&nbsp;&nbsp;'
2987 +'<button id="submitSave" name="submitSave" class="btn btn-info" style="font-size: 40px"> Submit</button>&nbsp;&nbsp;'
2988 +'<button id="submitCancel" name="submitCancel" class="btn btn-info" style="font-size: 40px"> Cancel</button></form>');
2989 $('#submitSave').off("click").on("click",function() {
2990 //saveAs(file);
2991 download([tempFile], fileName,"text/plain;charset=utf-8")
2992
2993 new_suffix=$('#newSuffix').val();
2994 new_description=$('#newDescr').val();
2995 new_room=my_session+'_'+new_suffix;
2996 cdata ={"room":my_session, "NewSuffix": new_suffix,"NewDescription": new_description,"Session": temp }
2997 console.log("Save session : "+new_room);
2998 socket.emit("save_Session", cdata);
2999 $('#saveValidate').remove();
3000
3001 $('#notifications').html('<div id=gotoNewRoom height="10%" width="50%" style="font-size:75"></div>');
3002 $('#gotoNewRoom').append('Goto new room ?<br>'
3003 + '<input type="text" id="gNRnew_room" name="new room" value="'+ new_room +'" style="width:40%"></input>&nbsp;&nbsp;'
3004 +'<button id="ChangeRoomYes" name="ChangeRoomYes" class="btn btn-info" style="font-size: 40px">Yes</button>&nbsp;'
3005 +'<button id="ChangeRoomNo" name="ChangeRoomNo" class="btn btn-info" style="font-size: 40px">No</button>');
3006
3007 $('#ChangeRoomYes').off("click").on("click",function() {
3008 new_room=$('#gNRnew_room').val();
3009 cdata ={"room":my_session, "NewRoom": new_room }
3010 $('#gGnewroom').val(new_room);
3011 socket.emit("deploy_Session", cdata);
3012 });
3013
3014 $('#ChangeRoomNo').off("click").on("click",function() {
3015 $('#gotoNewRoom').remove();
3016 });
3017 });
3018 $('#submitCancel').off("click").on("click",function() {
3019 $('#saveValidate').remove();
3020 });
3021 });
3022 });
3023 managementGlobalMenuIconClassAttributesTab.push("saveButtonIcon");
3024 managementGlobalMenuShareEvent.push(false);
3025
3029 managementGlobalMenuTitleTab.push("Option menu")
3030 managementGlobalMenuEventTab.push( function(v, id, optionNumber){
3031 if(v == true) {
3032 $('header').append("<div id=options class='dropbtn'></div>");
3033 $("#options").css({//GLOBALCSS
3034 position : "fixed",
3035 top : 0,
3036 left: parseInt($(me.menu.getHtmlMenuSelector()).css("width")),
3037 height: "100%",
3038 zIndex: 902,
3039 width :window.innerWidth - parseInt($(me.menu.getHtmlMenuSelector()).css("width")), // To have the upper right part of the screen
3040 //backgroundColor : "white", // TO DO : unify color style with the help menu + set color change for the wall
3041 //color : "black",
3042 fontSize : 100
3043 });
3044
3045 $('#options').append("<div id=options-zone></div>");
3046 $('#options-zone').append("<div id=options-menus class=option-group></div>");
3047
3048 // Menus behaviour
3049 //$('#options-zone').append("<div id=options-menus class=option-group></div>");
3050 //$('#options-menus').append("<div id=options-menus-label class=label>Menus</div>");
3051 $('#options-menus').append('<div id=dropdownglobal class="drop-left-menu" ></div>');
3052 $('#dropdownglobal').css({
3053 position: 'absolute',
3054 top: 40,
3055 left: 200,
3056 width: 100,
3057 height: 100,
3058 zIndex: 130,
3059 });
3060
3061 $('#options-menus').append("<div id=options-global-menu-label class='label'>Share global menu</div>");
3062 var thisMenuShareEvent=me.menu.getMenuShareEvent();
3063 var thisIconTab=me.menu.getMenuIconClassAttributesTab();
3064 var LocalMenus=Array();
3065 var GlobalMenuLabelState=false;
3066 var SubmenuLabelState=false;
3067 var SubmenusLabelState={};
3068
3069 for (var theOption in thisIconTab) {
3070 $('#options-global-menu-label')
3071 .append("<div id='shareDivMenu_"+thisIconTab[theOption]+"' style='font-size:100'></div>");
3072 $("#shareDivMenu_"+thisIconTab[theOption]).hide()
3073 .append("</br><input type='checkbox' id='shareMenu_"+thisIconTab[theOption]+"' name='shareMenu_"+thisIconTab[theOption]+"' value='yes' >"+
3074 thisIconTab[theOption].replace("GlobalMenu","Menu").replace("ButtonIcon",""));
3075 $('input[name=shareMenu_'+thisIconTab[theOption]+']').attr("checked",thisMenuShareEvent[theOption]);
3076 if (thisIconTab[theOption].search("GlobalMenu") > -1)
3077 LocalMenus.push(thisIconTab[theOption])
3078 }
3079
3080 $('#dropdownglobal').on({
3081 click : function(e) {
3082 if (GlobalMenuLabelState) {
3083 GlobalMenuLabelState=false;
3084 $('#dropdownglobal').removeClass("drop-down-menu").addClass("drop-left-menu");
3085 for (var theOption in thisIconTab) {
3086 $("#shareDivMenu_"+thisIconTab[theOption]).hide();
3087 }
3088 } else {
3089 GlobalMenuLabelState=true;
3090 $('#dropdownglobal').removeClass("drop-left-menu").addClass("drop-down-menu");
3091 for (var theOption in thisIconTab) {
3092 $("#shareDivMenu_"+thisIconTab[theOption]).show();
3093 }
3094 }
3095 }
3096 });
3097
3098 $('#options-menus').append('<br><br><div id=dropdownsubm class="drop-left-menu"></div>');
3099 $('#dropdownsubm').css({
3100 position: 'relative',
3101 top: 80,
3102 left: 200,
3103 width: 100,
3104 height: 100,
3105 zIndex: 130,
3106 });
3107 $('#options-menus').append("<div id=options-submenus-label class='label' style='font-size:95'>Share sub-menus</div>");
3108 for (var locMenu in LocalMenus) {
3109 var menuname=LocalMenus[locMenu].replace("GlobalMenuButtonIcon","Global");
3110 var thismenu=subMenusGlobal.filter(menu=>menu.getId()==menuname)[0];
3111 var thismenuShareEvent=thismenu.getMenuShareEvent();
3112 var thisiconTab=thismenu.getMenuIconClassAttributesTab();
3113
3114 $('#options-submenus-label').append('<br><div id="dropdownsubm_'+menuname+'" class="drop-left-menu"></div>');
3115 $('#dropdownsubm_'+menuname).css({
3116 position: 'relative',
3117 top: 80,
3118 left: 240,
3119 width: 100,
3120 height: 100,
3121 zIndex: 130,
3122 transform: "scale(0.75)"
3123 }).hide();
3124
3125 $('#options-submenus-label').append("<div id='shareDivSubmenu_"+menuname+"' style='font-size:85'>"+menuname+"</div>");
3126 $("#shareDivSubmenu_"+menuname).hide();
3127 SubmenusLabelState[menuname]=false;
3128
3129 for (var theOption in thisiconTab) {
3130 $("#shareDivSubmenu_"+menuname)
3131 .append("<div id=options-submenu-"+menuname+"-"+thisiconTab[theOption]+" ></div>");
3132 $("#options-submenu-"+menuname+"-"+thisiconTab[theOption]).hide()
3133 .append("<br><input type='checkbox' id='shareMenu_"+thisiconTab[theOption]+"' name='shareMenu_"+thisiconTab[theOption]+"' value='yes'>"+
3134 thisiconTab[theOption].replace("ButtonIcon",""));
3135 $('input[name=shareMenu_'+thisiconTab[theOption]+']').attr("checked",thismenuShareEvent[theOption]);
3136 }
3137
3138 $('#dropdownsubm_'+menuname).on({
3139 click : function(e) {
3140 var menuname=this.id.replace("dropdownsubm_","");
3141 var thismenu=subMenusGlobal.filter(menu=>menu.getId()==menuname)[0];
3142 var thisiconTab=thismenu.getMenuIconClassAttributesTab();
3143 if (SubmenusLabelState[menuname]) {
3144 SubmenusLabelState[menuname]=false;
3145 $('#dropdownsubm_'+menuname).removeClass("drop-down-menu").addClass("drop-left-menu");
3146 for (var theOption in thisiconTab) {
3147 $("#options-submenu-"+menuname+"-"+thisiconTab[theOption]).hide()
3148 }
3149 } else {
3150 SubmenusLabelState[menuname]=true;
3151 $('#dropdownsubm_'+menuname).removeClass("drop-left-menu").addClass("drop-down-menu");
3152 for (var theOption in thisiconTab) {
3153 $("#options-submenu-"+menuname+"-"+thisiconTab[theOption]).show();
3154 }
3155 }
3156 }
3157 });
3158 }
3159
3160
3161 $('#dropdownsubm').on({
3162 click : function(e) {
3163 if (SubmenuLabelState) {
3164 SubmenuLabelState=false;
3165 $('#dropdownsubm').removeClass("drop-down-menu").addClass("drop-left-menu");
3166 for (var locMenu in LocalMenus) {
3167 var menuname=LocalMenus[locMenu].replace("GlobalMenuButtonIcon","Global");
3168 $('#dropdownsubm_'+menuname).hide();
3169 $("#shareDivSubmenu_"+menuname).hide();
3170 }
3171 } else {
3172 SubmenuLabelState=true;
3173 $('#dropdownsubm').removeClass("drop-left-menu").addClass("drop-down-menu");
3174 for (var locMenu in LocalMenus) {
3175 var menuname=LocalMenus[locMenu].replace("GlobalMenuButtonIcon","Global");
3176 $('#dropdownsubm_'+menuname).show();
3177 $("#shareDivSubmenu_"+menuname).show();
3178 }
3179 }
3180 }
3181 });
3182
3183 setColorTheme(configColors.colorTheme);
3184
3185 $('#options-zone').append("<div id=options-look class=option-group></div>");
3186
3187 // Color theme
3188 $('#options-look').append("<div id=options-color-theme-label class=label>Color theme</div>");
3189 $('#options-look').append("<form id=options-color-theme-form>");
3190 $('#options-look').append("<input type='radio' name='color-theme-radio' value='dark'/>Dark<br />");
3191 $('#options-look').append("<input type='radio' name='color-theme-radio' value='light'/>Light<br />");
3192 $('#options-look').append("</form><br>");
3193 $('input[name=color-theme-radio][value=' + configColors.colorTheme + ']').attr("checked", true);
3194
3195 // Help tooltip => Option NOT USED in Menu.js because only defined at startup
3196 // $('#options-look').append("<div id=options-tooltip-label class=label>Tooltip</div>");
3197 // $('#options-look').append("<input type='checkbox' name=enable-tooltip value="+ configBehaviour.tooltip +">Enable Tooltip<br /><br />");
3198 // $('input[name=enable-tooltip]').attr("checked",configBehaviour.tooltip);
3199
3200 // Opacity slider
3201 $('#options-look').append("<div id=options-opacity-label class=label>Opacity</div>");
3202 $('#options-look').append("<input id=opacitySlider type='range' name=opacitySlider min=0 max=100 value= " +
3203 configBehaviour.opacity*100 + " oninput='opacitySliderOutputId.value=opacitySlider.value.toString()+ \"%\"'>");
3204 $('#options-look').append("<output name=opacitySliderOutput id=opacitySliderOutputId for=opacitySlider "+
3205 "style='font-size: 80px; padding: 20px; padding-top: 5px; padding-bottom: 5px;'>"+
3206 configBehaviour.opacity*100 +"%</output><br /><br />");
3207 $('#opacitySlider').change(function () {
3208 var val = ($(this).val() - $(this).attr('min')) / ($(this).attr('max') - $(this).attr('min'));
3209
3210 $(this).css('background-image',
3211 '-webkit-gradient(linear, left top, right top, '
3212 + 'color-stop(' + val + ', rgb(255, 0, 0)), '
3213 + 'color-stop(' + val + ', rgb(0, 255, 0))'
3214 + ')'
3215 );
3216 });
3217 //$('#opacitySliderOutputId').css('background-image', '');
3218
3219 // Primary Zoom Slider
3220 $('#options-look').append("<div id=options-primaryZoomSlider-label class=label>Global Zoom Slider</div>");
3221 $('#options-look').append("<input type='checkbox' name=enable-primaryZoom value="+ configBehaviour.primaryZoomSlider +">Enable primary Zoom Slider<br />");
3222 if (parseBool(configBehaviour.primaryZoomSlider))
3223 $('input[name=enable-primaryZoom]').attr("checked",configBehaviour.primaryZoomSlider);
3224
3225 // Primary Zoom Slider
3226 $('#options-look').append("<div id=options-globalVerticalSlider-label class=label>Global Vertical Slider</div>");
3227 var gVS=false;
3228 $('#options-look').append("<input type='checkbox' name=enable-globalVertical value="+gVS+">Enable browser vertical slider<br />");
3229 if (parseBool(gVS))
3230 $('input[name=enable-globalVertical]').attr("checked",gVS);
3231
3232 // Spread
3233 $('#options-zone').append("<div id=options-spread class=option-group></div>");
3234 $('#options-spread').append("<div id=options-spread-label class=label>Tile size</div>");
3235 $('#options-spread').append("<input type='checkbox' name=spread-keepratio value="+ configBehaviour.defaultKeepRatio +">Keep ratio<br />");
3236 if (parseBool(configBehaviour.defaultKeepRatio))
3237 $('input[name=spread-keepratio]').attr("checked",configBehaviour.defaultKeepRatio);
3238
3239 $('#options-spread').append("X: <input id=spreadX name=spreadX type='number' value=" +spread.X +">px ");
3240 $('#options-spread').append("Y: <input id=spreadY name=spreadY type='number' value=" +spread.Y +">px <br />");
3241 $('#options-spread').append("Number of columns:</br><input id=colNumber name=colNumber type='number' value=" +numOfColumns+ "><br />");
3242 $('#options-spread').append("Space Between </br>Columns:<input id=spaceBetweenColumns name=spaceBetweenColumns type='number' value=" +gapBetweenColumns+ "><br />");
3243 $('#options-spread').append("Lines:<input id=spaceBetweenLines name=spaceBetweenLines type='number' value=" +gapBetweenLines+ "><br />");
3244
3245 var clickKR = function(){
3246 if ($('input[name=spread-keepratio]').is(":checked")) {
3247 //console.log("KR checked");
3248 $('input[name=spreadX]').off("change").on({
3249 change : function(){
3250 $('input[name=spreadX]').val($('input[name=spreadX]').val().replace(/[^0-9.]/g, ''))
3251 //console.log("changeX");
3252 var ratioX = $('input[name=spreadX]').val()/spread.X;
3253 //console.log(ratioX);
3254 $('input[name=spreadY]').val(spread.Y*ratioX);
3255 }
3256 });
3257 $('input[name=spreadY]').off("change").on({
3258 change : function(){
3259 $('input[name=spreadY]').val($('input[name=spreadY]').val().replace(/[^0-9.]/g, ''))
3260 //console.log("changeY");
3261 var ratioY = $('input[name=spreadY]').val()/spread.Y;
3262 //console.log(ratioY);
3263 $('input[name=spreadX]').val(spread.X*ratioY);
3264 }
3265 });
3266 } else {
3267 //console.log("KR unchecked");
3268 }
3269 };
3270
3271 $('input[name=spread-keepratio]').off("click").on({
3272 click : clickKR
3273 });
3274 if(configBehaviour.defaultKeepRatio) { // Simulate first click to check the box if default behaviour means it should be checked
3275 $('input[name=spread-keepratio]').click();
3276 }
3277
3278 // Always show info
3279 $('#options-zone').append("<div id=options-info class=option-group></div>");
3280 $('#options-info').append("<div id=options-showinfo-label class=label>Informations</div>");
3281 $('#options-info').append("<input type='checkbox' id='showinfo-cb' name='showinfo-cb' value="+configBehaviour.alwaysShowInfo+">Always show</input>");
3282 if (parseBool( configBehaviour.alwaysShowInfo))
3283 $('input[name=showinfo-cb]').attr("checked", configBehaviour.alwaysShowInfo);
3284 // Info style
3285 $('#options-info').append("<div id=options-info-font-label class=label>Font</div>");
3286 $('#options-info').append("<select id=options-info-font-select></select>");
3287 for (var it = 0;it<configBehaviour.infoFonts.length;it++) {
3288 $('#options-info-font-select').append("<option value='"+it+"'>"+configBehaviour.infoFonts[it].split(",")[0]+"</option>");
3289 if(it==configBehaviour.defaultFontIndex) {
3290 $('#options-info-font-select').val(it);
3291 }
3292 }
3293 $('#options-info').append("<div id=options-info-size-label class=label>Size</div>");
3294 $('#options-info').append("<input id=infoSize name=infoSize type='number' value="+ parseInt($('.info').css("font-size")) +"><h1> less than "+configBehaviour.maxInfoFontSize+"</h1>");
3295
3296 // Drag and drop behaviour
3297 $('#options-zone').append("<div id=options-dragdrop class=option-group></div>");
3298 $('#options-dragdrop').append("<div id=options-dragdrop-label class=label>Drag & drop</div>");
3299 $('#options-dragdrop').append("<input type='checkbox' id='show-only-border-cb' name='show-only-border-cb' value="+configBehaviour.moveOnlyABorder+">Show only the border</br></input>");
3300 if (parseBool( configBehaviour.moveOnlyABorder))
3301 $('input[name=show-only-border-cb]').attr("checked", configBehaviour.moveOnlyABorder);
3302 $('#options-dragdrop').append("<input type='checkbox' id='move-on-menu-item-cb' name='move-on-menu-item-cb' value="+configBehaviour.moveOnMenuOption+">Enable in menu items</br></input>");
3303 if (parseBool( configBehaviour.moveOnMenuOption))
3304 $('input[name=move-on-menu-item-cb]').attr("checked", configBehaviour.moveOnMenuOption);
3305 $('#options-dragdrop').append("<input type='checkbox' id='move-on-grid-cb' name='move-on-grid-cb' value="+configBehaviour.moveOnGrid+">Move on a grid</br></br></input>");
3306 if (parseBool( configBehaviour.moveOnGrid))
3307 $('input[name=move-on-grid-cb]').attr("checked", configBehaviour.moveOnGrid);
3308 $('#options-dragdrop').append("<input type='checkbox' id='showAnimationsLineColSwap' name='showAnimationsLineColSwap' value="+configBehaviour.showAnimationsLineColSwap+">Animate moves</br></input>");
3309 if (parseBool( configBehaviour.showAnimationsLineColSwap))
3310 $('input[name=showAnimationsLineColSwap]').attr("checked", configBehaviour.showAnimationsLineColSwap);
3311 $('#options-dragdrop').append("<br>Speed of animations:</br><input id=AnimationSpeed name=AnimationSpeed type='number' value=" +configBehaviour.animationSpeed+ "></br>");
3312
3313 // Zoom Nodes behaviour
3314 $('#options-zone').append("<div id=options-zoom class=option-group></div>");
3315 $('#options-zoom').append("<div id=options-sharedZoomNodes-label class=label>Shared zoom nodes</div>");
3316 $('#options-zoom').append("<input type='checkbox' name=enable-sharedzoomnodes value="+ configBehaviour.sharedZoomNodes +">Enable shared zoom nodes<br /></br>");
3317 if (parseBool(configBehaviour.sharedZoomNodes))
3318 $('input[name=enable-sharedzoomnodes]').attr("checked",configBehaviour.sharedZoomNodes);
3319
3320 $('#options-zoom').append("<input type='checkbox' name=enable-sharedSliderzoom value="+ configBehaviour.sharedSliderZoom +">Enable shared slider zoom<br /></br>");
3321 if (parseBool(configBehaviour.sharedSliderZoom))
3322 $('input[name=enable-sharedSliderzoom]').attr("checked",configBehaviour.sharedSliderZoom);
3323
3324 // master-slave behaviour
3325 $('#options-zoom').append("<div id=options-masterslave-label class=label>Parallel interaction</div>");
3326 $('#options-zoom').append("<br>Number of tiles showed:</br><input id=allMSShowMax name=allMSShowMax type='number' value=" +configBehaviour.allMSShowMax+ "></br>");
3327 $('#options-zoom').append("<br>Only MASTER in MS mode:</br><input id=onlyMasterMS name=onlyMasterMS type='checkbox' value=" +configBehaviour.onlyMasterMS+ "></br>");
3328 if (parseBool(configBehaviour.onlyMasterMS))
3329 $('input[name=onlyMasterMS]').attr("checked",configBehaviour.onlyMasterMS);
3330
3331 $('#options-zone').append("<div id=options-touch class=option-group></div>");
3332 // Touch behaviour
3333 $('#options-touch').append("<div id=options-touch-label class=label>Touchable device</div>");
3334 if (touchok) {
3335
3336 $('#options-touch').append("<br>Speed of touch:</br><input id=touchSpeed name=touchSpeed type='number' value=" +configBehaviour.touchSpeed+ "></br>");
3337 $('#options-touch').append("<input type='checkbox' id='touchon-window' name='touchon-window' value="+configBehaviour.touchonWindow+">Touch on window gesture</input></br>");
3338 if (parseBool( configBehaviour.touchonWindow))
3339 $('input[name=touchon-window]').attr("checked", configBehaviour.touchonWindow);
3340 }
3341 $('#options-touch').append("<input type='checkbox' id='smooth-rotation' name='smooth-rotation' value="+configBehaviour.smoothRotation+">Smooth rotation</input>");
3342 if (parseBool( configBehaviour.smoothRotation))
3343 $('input[name=smooth-rotation]').attr("checked", configBehaviour.smoothRotation);
3344
3345 $('#options-touch').append("<br>Speed of rotation:</br><input id=RotInc name=RotInc type='number' step='0.1' value=" +configBehaviour.RotationSpeed+ "></br>");
3346
3347 // Button to save and exit the options menu
3348 $('#options').append("<div id=buttonApply title='Apply for this browser'></div>");
3349
3350 // Button cancel modifications
3351 $('#options').append("<div id=buttonCancel title='Cancel changes'></div>");
3352
3353 // Button to save config in a file
3354 $('#options').append("<div id=buttonSave title='Apply and save options to a file'></div>");
3355
3356 // Button to share config to all clients in room
3357 $('#options').append("<div id=buttonShare title='Apply and share to other clients in session'</div>");
3358
3359 $('#'+id+'option'+optionNumber).attr('class', $('#'+id+'option'+optionNumber).attr('class').replace('optionsButtonIcon', 'closeOptionsButtonIcon'));
3360
3361 // Get all values
3362 ApplyParameters = function() {
3363 var tempColors = "'colors': {***}";
3364 // var tempJsonData = "'jsonData': {***}";
3365 var tempBehaviour = "'behaviour': {***}";
3366 // var tempTagBehaviour = "'tagBehaviour': {***}";
3367 // var tempCSSProperties = "'cssProperties': {***}";
3368
3369 if(configColors.colorTheme != $('input[name=color-theme-radio]').filter(':checked').val()) {
3370 configColors.colorTheme = $('input[name=color-theme-radio]').filter(':checked').val();
3371 setColorTheme(configColors.colorTheme);
3372 }
3373 tempColors=tempColors.replace("***","'colorTheme':'"+configColors.colorTheme+"'"+", ***");
3374
3375 // Help tooltip => Option NOT USED in Menu.js because only defined at startup
3376 // configBehaviour.tooltip = $('input[name=enable-tooltip]').is(":checked");
3377 // tempBehaviour=tempBehaviour.replace("***","'tooltip': '"+configBehaviour.tooltip+"', ***");
3378
3379 if(configBehaviour.opacity*100 != $('#opacitySlider').val()) {
3380 configBehaviour.opacity = Math.max($('#opacitySlider').val()/100, 0.1);
3381 for (O in nodesById) {
3382 nodesById[O].setNodeOpacity(configBehaviour.opacity);
3383 }
3384 }
3385 tempBehaviour=tempBehaviour.replace("***","'opacity':"+configBehaviour.opacity+", ***");
3386
3387 configBehaviour.primaryZoomSlider = $('input[name=enable-primaryZoom]').is(":checked");
3388 if (parseBool( configBehaviour.primaryZoomSlider )) {
3389 $('#primarySliderLabel').show();
3390 $('#primarySlider').show();
3391 $('#primarySlider').click();
3392 } else {
3393 $('#primarySliderLabel').hide();
3394 $('#primarySlider').hide();
3395 $('#primaryparent').css("transform","")
3396 $('#primaryparent').css("transform-origin","")
3397 }
3398
3399 var gVS = $('input[name=enable-globalVertical]').is(":checked");
3400 if (parseBool(gVS))
3401 document.body.setAttribute('style','overflow:hidden auto;');
3402 else
3403 document.body.setAttribute('style','overflow:hidden;');
3404
3405 var hasSpreadChanged = false;
3406 if(spread.X != $('input[name=spreadX]').val()) {
3407 if ( $('input[name=spreadX]').val() == "")
3408 $('input[name=spreadX]').val(spread.X)
3409 //console.log("change X, new", $('input[name=spreadX]').val());
3410 hasSpreadChanged = true;
3411 }
3412 if(spread.Y != $('input[name=spreadY]').val()) {
3413 if ( $('input[name=spreadY]').val() == "")
3414 $('input[name=spreadY]').val(spread.Y)
3415 //console.log("change Y, new", $('input[name=spreadY]').val());
3416 hasSpreadChanged = true;
3417 }
3418
3419 if(hasSpreadChanged) {
3420 $('input[name=spreadX]').val($('input[name=spreadX]').val().replace(/[^0-9.]/g, ''))
3421 $('input[name=spreadY]').val($('input[name=spreadY]').val().replace(/[^0-9.]/g, ''))
3422 var newSpread = {
3423 X : parseInt($('input[name=spreadX]').val()),
3424 Y : parseInt($('input[name=spreadY]').val())
3425
3426 };
3427 me.updateSpread(newSpread);
3428
3429 temp3="'spread': { 'X':"+newSpread.X+", 'Y':"+newSpread.Y+"}";
3430 tempBehaviour=tempBehaviour.replace("***",temp3+", ***");
3431 }
3432
3433 //console.log(parseInt($('input[name=colNumber]').val()));
3434 numOfColumns = parseInt($('input[name=colNumber]').val());
3435 tempBehaviour=tempBehaviour.replace("***","'maxNumOfColumns': "+numOfColumns+", ***");
3436
3437 gapBetweenColumns = parseInt($('input[name=spaceBetweenColumns]').val());
3438 tempBehaviour=tempBehaviour.replace("***","'spaceBetweenColumns': "+gapBetweenColumns+", ***");
3439
3440 gapBetweenLines = parseInt($('input[name=spaceBetweenLines]').val());
3441 tempBehaviour=tempBehaviour.replace("***","'spaceBetweenLines': "+gapBetweenLines+", ***");
3442
3443 maxNumOfColumns=numOfColumns;
3444 mesh.globalLocationProvider();
3445
3446 configBehaviour.alwaysShowInfo = $('input[name=showinfo-cb]').is(":checked");
3447 tempBehaviour=tempBehaviour.replace("***","'alwaysShowInfo': '"+configBehaviour.alwaysShowInfo+"', ***");
3448
3449 if(parseInt($('.info').css("font-size"))!=$('#infoSize').val()) {
3450 $('.info').css("font-size", Math.min($('#infoSize').val(), configBehaviour.maxInfoFontSize) + "px");
3451 configBehaviour.defaultInfoFontSize = $('.info').css("font-size");
3452
3453 tempBehaviour=tempBehaviour.replace("***","'defaultInfoFontSize': '"+configBehaviour.defaultInfoFontSize+"', ***");
3454 }
3455 configBehaviour.defaultFontIndex = $('#options-info-font-select').val();
3456 $('.info').css("font-family", configBehaviour.infoFonts[configBehaviour.defaultFontIndex]);
3457
3458 tempBehaviour=tempBehaviour.replace("***","'defaultFontIndex': "+configBehaviour.defaultFontIndex+", ***");
3459
3460 configBehaviour.moveOnlyABorder = $('input[name=show-only-border-cb]').is(":checked");
3461 tempBehaviour=tempBehaviour.replace("***","'moveOnlyABorder': '"+configBehaviour.moveOnlyABorder+"', ***");
3462 configBehaviour.moveOnMenuOption = $('input[name=move-on-menu-item-cb]').is(":checked");
3463 tempBehaviour=tempBehaviour.replace("***","'moveOnMenuOption': '"+configBehaviour.moveOnMenuOption+"', ***");
3464 configBehaviour.moveOnGrid = $('input[name=move-on-grid-cb]').is(":checked");
3465 tempBehaviour=tempBehaviour.replace("***","'moveOnGrid': '"+configBehaviour.moveOnGrid+"', ***");
3466 configBehaviour.showAnimationsLineColSwap = $('input[name=showAnimationsLineColSwap]').is(":checked");
3467 tempBehaviour=tempBehaviour.replace("***","'showAnimationsLineColSwap': '"+configBehaviour.showAnimationsLineColSwap+"', ***");
3468
3469 configBehaviour.animationSpeed = $('#AnimationSpeed').val();
3470 tempBehaviour=tempBehaviour.replace("***","'animationSpeed': "+configBehaviour.animationSpeed+", ***");
3471
3472 configBehaviour.sharedZoomNodes = $('input[name=enable-sharedzoomnodes]').is(":checked");
3473 tempBehaviour=tempBehaviour.replace("***","'sharedZoomNodes': '"+configBehaviour.sharedZoomNodes+"', ***");
3474
3475 configBehaviour.sharedSliderZoom = $('input[name=enable-sharedSliderzoom]').is(":checked");
3476 tempBehaviour=tempBehaviour.replace("***","'sharedSliderZoom': '"+configBehaviour.sharedSliderZoom+"', ***");
3477
3478 configBehaviour.allMSShowMax = $('#allMSShowMax').val();
3479 tempBehaviour=tempBehaviour.replace("***","'allMSShowMax': "+configBehaviour.allMSShowMax+", ***");
3480
3481 configBehaviour.onlyMasterMS = $('#onlyMasterMS').val();
3482 tempBehaviour=tempBehaviour.replace("***","'onlyMasterMS': "+configBehaviour.onlyMasterMS+", ***");
3483
3484 if (touchok) {
3485 configBehaviour.touchSpeed = $('#touchSpeed').val();
3486 tempBehaviour=tempBehaviour.replace("***","'touchSpeed': "+configBehaviour.touchSpeed+", ***");
3487
3488 configBehaviour.touchonWindow = $('#touchon-window').val();
3489 if (parseBool(configBehaviour.touchonWindow)) {
3490 document.body.setAttribute('style','overflow:auto;');
3491 } else {
3492 document.body.setAttribute('style','overflow:hidden;');
3493 }
3494 tempBehaviour=tempBehaviour.replace("***","'touchonWindow': "+configBehaviour.touchonWindow+", ***");
3495 }
3496
3497 configBehaviour.smoothRotation = $('input[name=smooth-rotation]').is(":checked");
3498 tempBehaviour=tempBehaviour.replace("***","'smoothRotation': '"+configBehaviour.smoothRotation+"', ***");
3499 if (parseBool(configBehaviour.smoothRotation)) {
3500 configBehaviour.RotationSpeed=$('#RotInc').val();
3501 tempBehaviour=tempBehaviour.replace("***","'RotationSpeed': '"+configBehaviour.smoothRotation+"', ***");
3502 RotInc=parseFloat(configBehaviour.RotationSpeed); //for a smooth touchmove rotation
3503 } else {
3504 // for a turn over with only touchstart / touchend (no touchmove) events
3505 RotInc=180;
3506 }
3507
3508 temp3="'shareMenu': { ";
3509 tempBehaviour=tempBehaviour.replace("***",temp3+" ***");
3510
3511 for (var theOption in thisIconTab) {
3512 ThisMenuShared=$('input[name=shareMenu_'+thisIconTab[theOption]+']').is(":checked");
3513 me.menu.setMenuShareEvent(theOption, ThisMenuShared);
3514 tempBehaviour=tempBehaviour.replace("***","'"+thisIconTab[theOption]+"': '"+ThisMenuShared+"', ***");
3515 }
3516 for (var locMenu in LocalMenus) {
3517 var menuname=LocalMenus[locMenu].replace("GlobalMenuButtonIcon","Global")
3518 var thismenu=subMenusGlobal.filter(menu=>menu.getId()==menuname)[0];
3519 var thisiconTab=thismenu.getMenuIconClassAttributesTab();
3520 for (var theOption in thisiconTab) {
3521 ThisMenuShared=$('input[name=shareMenu_'+thisiconTab[theOption]+']').is(":checked");
3522 thismenu.setMenuShareEvent(theOption, ThisMenuShared);
3523 tempBehaviour=tempBehaviour.replace("***","'"+thisiconTab[theOption]+"': '"+ThisMenuShared+"', ***");
3524 }
3525 }
3526
3527 temp3="}";
3528 tempBehaviour=tempBehaviour.replace(", ***",temp3+", ***");
3529
3530 var tempConfigJson="{"
3531 + tempColors.replace(", ***","").replace("***","")+","
3532 // + tempJsonData.replace(",\n ***","").replace("***","")+",\n"
3533 + tempBehaviour.replace(", ***","").replace("***","")
3534 // + tempTagBehaviour.replace(",\n ***","").replace("***","")+",\n"
3535 // + tempCSSProperties.replace(",\n ***","").replace("***","")+"\n"
3536 + "}";
3537
3538 return tempConfigJson.replaceAll("'",'"');
3539 }
3540
3541
3542 // Interactions
3543 $('#buttonApply').off("click").on({
3544
3545 click : function(){
3546 ApplyParameters();
3547 $('#buttonCancel').click();
3548 }
3549 });
3550
3551 $('#buttonCancel').off("click").on('click',function() {
3552 $('#'+id+'option'+optionNumber).click();
3553 });
3554
3555 $('#buttonSave').off("click").on({
3556 click : function(){
3557 ConfigJson = ApplyParameters();
3558
3559 var sessionDate = new Date();
3560 var strDate=sessionDate.toLocaleDateString({day: "2-digit", month: "2-digit"}).replace(/\//g, "-") + "_" + sessionDate.toLocaleTimeString("fr-FR").replace(/:/g, "-")
3561 var fileName = my_session + "_" + "Config_" + strDate + ".json";
3562 //var file = new File([ConfigJson], fileName, {type: "text/plain;charset=utf-8"},{ autoBom: false });
3563 //saveAs(file);
3564 download([ConfigJson], fileName, {type: "text/plain;charset=utf-8"})
3565 addBlink(this)
3566
3567 // Force save config in DB too.
3568 cdata ={"room":my_session, "Config": ConfigJson.replaceAll("'",'"') }
3569 console.log("Share config : "+ConfigJson);
3570 // used to deploy config but not on the user that have emited the signal.
3571 myOwnConfig=true;
3572 socket.emit("share_Config", cdata);
3573 }
3574 });
3575
3576 $('#buttonShare').off("click").on({
3577 click : function(){
3578 ConfigJson = ApplyParameters();
3579
3580 cdata ={"room":my_session, "Config": ConfigJson.replaceAll("'",'"') }
3581 console.log("Share config : "+ConfigJson);
3582 // used to deploy config but not on the user that have emited the signal.
3583 myOwnConfig=true;
3584 socket.emit("share_Config", cdata);
3585 addBlink(this)
3586 }
3587 });
3588
3589 } else {
3590 $('#options').remove();
3591 $('#options-content-select').remove();
3592 $('#'+id+'option'+optionNumber).removeClass("closeOptionsButtonIcon").addClass("optionsButtonIcon");
3593 }
3594 });
3595
3596 managementGlobalMenuIconClassAttributesTab.push("optionsButtonIcon");
3597 managementGlobalMenuShareEvent.push(false);
3598
3599
3600 // Update parameters for options
3601 UpdateParameters = function(configJson) {
3602 var tempColors = configJson.colors;
3603 // var tempJsonData = configJson.jsonData;
3604 var tempBehaviour = configJson.behaviour;
3605 // var tempTagBehaviour = configJson.tagBehaviour;
3606 // var tempCSSProperties = configJson.cssProperties;
3607
3608 if (tempColors.hasOwnProperty('colorTheme')) {
3609 configColors.colorTheme = tempColors.colorTheme
3610 setColorTheme(configColors.colorTheme);
3611 }
3612
3613 // Help tooltip => Option NOT USED in Menu.js because only defined at startup
3614 // if(tempBehaviour.hasOwnProperty('tooltip'))
3615 // configBehaviour.tooltip = $.parseJSON(tempBehaviour.tooltip);
3616
3617 if(tempBehaviour.hasOwnProperty('opacity')) {
3618 configBehaviour.opacity = tempBehaviour.opacity;
3619 for (O in nodesById) {
3620 nodesById[O].setNodeOpacity(configBehaviour.opacity);
3621 }
3622 }
3623
3624 if(tempBehaviour.hasOwnProperty('spread')) {
3625 var newSpread = {
3626 X : parseInt(tempBehaviour.spread.X),
3627 Y : parseInt(tempBehaviour.spread.Y)
3628
3629 };
3630 me.updateSpread(newSpread);
3631 }
3632
3633 if(tempBehaviour.hasOwnProperty('maxNumOfColumns'))
3634 numOfColumns = tempBehaviour.maxNumOfColumns;
3635
3636 if(tempBehaviour.hasOwnProperty('spaceBetweenColumns'))
3637 gapBetweenColumns = tempBehaviour.spaceBetweenColumns
3638 if(tempBehaviour.hasOwnProperty('spaceBetweenLines'))
3639 gapBetweenLines = tempBehaviour.spaceBetweenLines
3640
3641 maxNumOfColumns=numOfColumns;
3642 mesh.globalLocationProvider();
3643
3644 if(tempBehaviour.hasOwnProperty('alwaysShowInfo'))
3645 configBehaviour.alwaysShowInfo = $.parseJSON(tempBehaviour.alwaysShowInfo);
3646
3647 if(tempBehaviour.hasOwnProperty('defaultInfoFontSize')) {
3648 configBehaviour.defaultInfoFontSize = tempBehaviour.defaultInfoFontSize;
3649 $('.info').css("font-size",configBehaviour.defaultInfoFontSize)
3650 }
3651 if(tempBehaviour.hasOwnProperty('defaultFontIndex')) {
3652 configBehaviour.defaultFontIndex = tempBehaviour.defaultFontIndex;
3653 $('.info').css("font-family", configBehaviour.infoFonts[configBehaviour.defaultFontIndex]);
3654 }
3655
3656 if(tempBehaviour.hasOwnProperty('moveOnlyABorder'))
3657 configBehaviour.moveOnlyABorder = $.parseJSON(tempBehaviour.moveOnlyABorder);
3658
3659 if(tempBehaviour.hasOwnProperty('moveOnMenuOption'))
3660 configBehaviour.moveOnMenuOption = $.parseJSON(tempBehaviour.moveOnMenuOption);
3661
3662 if(tempBehaviour.hasOwnProperty('moveOnGrid'))
3663 configBehaviour.moveOnGrid = $.parseJSON(tempBehaviour.moveOnGrid);
3664
3665 if(tempBehaviour.hasOwnProperty('showAnimationsLineColSwap'))
3666 configBehaviour.showAnimationsLineColSwap = $.parseJSON(tempBehaviour.showAnimationsLineColSwap);
3667
3668 if(tempBehaviour.hasOwnProperty('animationSpeed'))
3669 configBehaviour.animationSpeed = tempBehaviour.animationSpeed;
3670
3671 if(tempBehaviour.hasOwnProperty('allMSShowMax'))
3672 configBehaviour.allMSShowMax = tempBehaviour.allMSShowMax;
3673
3674 if(tempBehaviour.hasOwnProperty('onlyMasterMS'))
3675 configBehaviour.onlyMasterMS = tempBehaviour.onlyMasterMS;
3676
3677 if (touchok) {
3678
3679 if(tempBehaviour.hasOwnProperty('touchSpeed'))
3680 configBehaviour.touchSpeed = tempBehaviour.touchSpeed;
3681 if(tempBehaviour.hasOwnProperty('touchonWindow'))
3682 configBehaviour.touchonWindow = tempBehaviour.touchonWindow;
3683 }
3684
3685 configBehaviour.smoothRotation = false;
3686 if(tempBehaviour.hasOwnProperty('smoothRotation'))
3687 configBehaviour.smoothRotation = $.parseJSON(tempBehaviour.smoothRotation);
3688
3689 if (parseBool(configBehaviour.smoothRotation)) {
3690 if(tempBehaviour.hasOwnProperty('RotationSpeed'))
3691 configBehaviour.RotationSpeed = $.parseJSON(tempBehaviour.RotationSpeed);
3692 RotInc=parseFloat(configBehaviour.RotationSpeed); //for a smooth touchmove rotation
3693 } else {
3694 // for a turn over with only touchstart / touchend (no touchmove) events
3695 RotInc=180;
3696 }
3697
3698 }
3699
3702
3703 var initHelp=null;
3704
3705 managementGlobalMenuTitleTab.push("Show help page")
3706 managementGlobalMenuEventTab.push( function(v, id, optionNumber){
3707 if (v==true) {
3708 //var support = document.getElementById("helpframe");
3709
3710 if (initHelp == null) { // First time opening the help menu: Help page will be loaded
3711 htmlPrimaryParent.prepend($('#helpSupport'));
3712 $('#helpSupport').css({ // TO BE CONTINUED !
3713 position : "absolute",
3714 //top : parseInt($('#header').css('height')),
3715 top : 0,
3716 //padding : "100px",
3717 left : parseInt($(me.menu.getHtmlMenuSelector()).css("width")),
3718 zIndex : 750,
3719 height : "100%",
3720 width : "100%",
3721 backgroundColor : "black",
3722 opacity : 1
3723 });
3724
3725
3726 $('#helpframe').attr("height","30%").attr("width","30%").css({
3727 height: "30%",
3728 width : "30%"
3729 });
3730
3731 console.log(helpPath);
3732 $('#helpSupport').append('<div id=buttonClosehelp class=unzoomButtonIcon></div>');
3733 $('#helpSupport').append("<div id=helpSliderLabel style='background-image: none; color: white; background-color: black; font-size: 80px; padding: 20px; padding-top: 5px; padding-bottom: 5px;'>Zoom</div>");
3734 $('#buttonClosehelp').css({
3735 position : "fixed",
3736 top : 0 ,
3737 left : parseInt($(me.menu.getHtmlMenuSelector()).css("width")),
3738 height : 200,
3739 width : 200,
3740 zIndex : 802,
3741 backgroundColor: "rgba(0, 0, 0, 0.5)"
3742 });
3743 $('#buttonClosehelp').off("click").on('click',function() {
3744 $('#helpSupport').hide();
3745 $('#'+id +'option'+optionNumber).removeClass("closeHelpButtonIcon").addClass("helpButtonIcon")
3746 });
3747
3748 $('#helpSliderLabel').css({
3749 position: "fixed",
3750 fontSize : "150px",
3751 left : parseInt($(me.menu.getHtmlMenuSelector()).css("width"))
3752 +parseInt($('#buttonClosehelp').css("width")),
3753 top: 10,
3754 //color: "white",
3755 zIndex: 802,
3756 padding: "0px 50px",
3757 width : "600px",
3758 height : "200px"
3759 //backgroundColor: "rgba(0, 0, 0, 0.5)"
3760 });
3761
3762 $('#helpSliderLabel').append("<input id=helpSlider type='range' name=helpSlider min="+window.devicePixelRatio*100+" max="+5*window.devicePixelRatio*100+" value= " +
3763 3*window.devicePixelRatio*100 + ">");
3764
3765 $('#helpSlider').css({
3766 position : "fixed",
3767 top: parseInt($('#helpSliderLabel').css("height"))/2,
3768 left : (parseInt($('#helpSliderLabel').css("width"))
3769 +parseInt($('#buttonClosehelp').css("width")))*1.1,
3770 //width : 30/100 * parseInt($('header').css("width"))
3771 width: parseInt($('header').css("width"))/2 - parseInt($(me.menu.getHtmlMenuSelector()).css("width")),
3772 //padding : parseInt($('#helpSliderLabel').css("height"))/2,
3773 });
3774
3775 $('#helpSlider').change(function () {
3776 var val = ($(this).val() - $(this).attr('min')) / ($(this).attr('max') - $(this).attr('min'));
3777
3778 $(this).css('background-image',
3779 '-webkit-gradient(linear, left top, right top, '
3780 + 'color-stop(' + val + ', rgb(255, 0, 0)), '
3781 + 'color-stop(' + val + ', rgb(0, 255, 0))'
3782 + ')'
3783 );
3784 });
3785
3786 var val = ($("#helpSlider").val() - $("#helpSlider").attr('min')) / ($("#helpSlider").attr('max') - $("#helpSlider").attr('min'));
3787 $('#helpSlider').css('background-image',
3788 '-webkit-gradient(linear, left top, right top, '
3789 + 'color-stop(' + val + ', rgb(255, 0, 0)), '
3790 + 'color-stop(' + val + ', rgb(0, 255, 0))'
3791 + ')'
3792 );
3793
3794
3795 $('#helpframe').css({
3796 position: "fixed",
3797 top : parseInt($('#helpSliderLabel').css("height"))
3798 });
3799
3800 $('#helpSlider').off("click").on({
3801 click : function(e){
3802 var newZoom = $('#helpSlider').val();
3803 var ratio = newZoom/(window.devicePixelRatio*100);
3804 $('#helpframe').css("-moz-transform","scale("+ratio+")").css("-webkit-transform","scale("+ratio+")").css("transform-origin", "0 0 0");
3805 }
3806 });
3807
3808 $('#helpSlider').click();
3809 //$('#helpSupport').load("doc/user_doc_EN.html");
3810
3811 setColorTheme(configColors.colorTheme); // First time: set colors
3812 $('#helpSupport').show();
3813
3814 initHelp="ok";
3815 } else // Simply show the previous (hidden since) help page.
3816 {
3817 $('#helpSupport').show();
3818 }
3819
3820 $('#'+id+'option'+optionNumber).removeClass("helpButtonIcon").addClass("closeHelpButtonIcon");
3821 } else
3822 $('#buttonClosehelp').click();
3823 });
3824 managementGlobalMenuIconClassAttributesTab.push("helpButtonIcon");
3825 managementGlobalMenuShareEvent.push(false);
3826
3831
3832 var cancelGlobalMenuTitleTab = new Array();
3833 var cancelGlobalMenuEventTab = new Array();
3834 var cancelGlobalMenuIconClassAttributesTab = new Array();
3835 var cancelGlobalMenuShareEvent = new Array();
3836
3837 // Cancel last movement
3838 cancelGlobalMenuTitleTab.push("Cancel last movement")
3839 cancelGlobalMenuEventTab.push(( function(){
3840
3841 return function(v){
3842 if(!(nodesOldPositions.length-stepBack == -1)) { // ie nodesOldPositions.length != 0, ie there is/are movement(s) to cancel
3843 if(stepBack==1) {
3844 //console.log("stepback == 1");
3845 me.savePositions();
3846 stepBack++;
3847 }
3848
3849 var back = function(){
3850
3851 var u = 0;
3852
3853 for(u=0;u<nodesByLoc.length;u++) {
3854 me.switchLocation(me.getNode(nodesOldPositions[nodesOldPositions.length-stepBack][u]),nodesByLoc[u],true,false);
3855 }
3856 // If the last movement was a "block movement", ie column or line swap, undo the
3857 // swap with only one click
3858 if (nodesOldPositions[nodesOldPositions.length - stepBack][nodesByLoc.length]) {
3859 stepBack ++;
3860 back();
3861 }
3862 }
3863
3864 if(v==true) {
3865 back();
3866 } else {
3867 back();
3868 }
3869
3870 stepBack++;
3871
3872 }
3873
3874 };
3875 })());
3876
3877 cancelGlobalMenuIconClassAttributesTab.push("moveBackButtonIcon");
3878 cancelGlobalMenuShareEvent.push(true);
3879
3881
3882 // var ctrlpress = false;
3883 // var altpress = false;
3884 // var sizeMenuEventTab = menuEventTab.length-1;
3885 // $("body").on({
3886 // keydown : function(e){
3887 // //CTRL
3888 // if(e.keyCode==17) {
3889 // ctrlpress=true;
3890
3891 // $("body").on({
3892
3893 // keydown : function(e){
3894 // //Z
3895 // if(e.keyCode==90 && ctrlpress==true) {
3896
3897 // menuGlobal.children(menuGlobal.attr("id").replace("menu","")+'option'+sizeMenuEventTab).click();//MARK
3898 // }
3899 // },
3900 // keyup : function(e){
3901 // //CTRL
3902 // if(e.keyCode==17) {
3903 // ctrlpress=false;
3904 // }
3905 // }
3906 // });
3907 // } //alt
3908 // // else
3909 // // if(e.keyCode==18)
3910 // // {
3911 // // altpress=true;
3912
3913 // // $("body").on({
3914
3915 // // keydown : function(e){
3916 // // //Z
3917 // // if(e.keyCode==90 && altpress==true)
3918 // // {
3919
3920 // // menuGlobal.children(menuGlobal.attr("id").replace("menu","")+'option'+sizeMenuEventTab).click();
3921 // // }
3922 // // },
3923 // // keyup : function(e){
3924 // // //ALT
3925 // // if(e.keyCode==18)
3926 // // {
3927 // // altpress=false;
3928 // // }
3929 // // }
3930 // // });
3931 // // }
3932 // }
3933 // });
3934
3935
3937 cancelGlobalMenuTitleTab.push("Redo last cancelled")
3938 cancelGlobalMenuEventTab.push(( function(){
3939
3940
3941 return function(v){
3942
3943 var stepForward = 1-stepBack; // It was 2-stepBack in Yacouba's code, and caused an error when trying to undo movements at the beginning, when they weren’t any (stepForward = 2-1 = 1, the loop was entered, but nodesOldPositions[nodes….length + 1] didn’t exist).
3944 //console.log(stepForward, stepBack);
3945 if(stepForward<0 && stepForward + nodesOldPositions.length >= 0) {
3946
3947
3948
3949 var forward = function(){
3950
3951 var u = 0;
3952
3953 //console.log(nodesOldPositions.length+stepForward);
3954 for(u=0;u<nodesByLoc.length;u++) {
3955 me.switchLocation(me.getNode(nodesOldPositions[nodesOldPositions.length+stepForward][u]),nodesByLoc[u],true,false);
3956 }
3957 // If the last undone movement was a block move, we want to detect it and re-do
3958 // it in one click
3959 if (stepForward + 1 <= -1) { // Condition on length : we want the "nodesOldPositions.length + stepForward +1"-th element, this index has to be smaller than "nodesOldPositions.length - 1"
3960 var boolCurrIdx = nodesOldPositions[nodesOldPositions.length+stepForward][nodesByLoc.length];
3961 var boolNextIdx = nodesOldPositions[nodesOldPositions.length+stepForward+1][nodesByLoc.length];
3962 //console.log(boolCurrIdx, boolNextIdx);
3963 if (boolNextIdx || boolCurrIdx) {
3964 //console.log("detected block");
3965 stepBack --;
3966 stepForward = 1-stepBack;
3967 //console.log(stepBack, stepForward);
3968
3969 if(stepForward<0 && stepForward >= -nodesOldPositions.length) { // Ensure no forbidden operations / access to unaccessible index in the array
3970 forward();
3971 }
3972 }
3973 } else {
3974 console.log("not in range (forward)");
3975 }
3976 }
3977
3978 if(v==true) {
3979 forward();
3980 } else {
3981 forward();
3982 }
3983
3984 stepBack--;
3985 }
3986 };
3987 })());
3988
3989 cancelGlobalMenuIconClassAttributesTab.push("moveForwardButtonIcon");
3990 cancelGlobalMenuShareEvent.push(true);
3991
3993
3994 // var ctrlpress = false;
3995 // //var altpress = false;
3996 // var sizeMenuEventTab2 = menuEventTab.length-1;
3997 // $("body").on({
3998 // keydown : function(e){
3999 // //CTRL
4000 // if(e.keyCode==17) {
4001 // ctrlpress=true;
4002
4003 // $("body").on({
4004
4005 // keydown : function(e){
4006 // //Y
4007 // if(e.keyCode==89 && ctrlpress==true) {
4008
4009 // menuGlobal.children(menuGlobal.attr("id").replace("menu","")+'option'+sizeMenuEventTab2).click();
4010 // }
4011 // },
4012 // keyup : function(e){
4013 // //CTRL
4014 // if(e.keyCode==17) {
4015 // ctrlpress=false;
4016 // }
4017 // }
4018 // });
4019 // } // alt
4020 // // else
4021 // // if(e.keyCode==18)
4022 // // {
4023 // // altpress=true;
4024
4025 // // $("body").on({
4026
4027 // // keydown : function(e){
4028 // // //Y
4029 // // if(e.keyCode==89 && altpress==true)
4030 // // {
4031 // // menuGlobal.children(menuGlobal.attr("id").replace("menu","")+'option'+sizeMenuEventTab2).click();
4032
4033 // // }
4034 // // },
4035 // // keyup : function(e){
4036 // // //ALT
4037 // // if(e.keyCode==18)
4038 // // {
4039 // // altpress=false;
4040 // // }
4041 // // }
4042 // // });
4043 // // }
4044 // }
4045 // });
4046
4051
4052 var updownGlobalMenuTitleTab = new Array();
4053 var updownGlobalMenuEventTab = new Array();
4054 var updownGlobalMenuIconClassAttributesTab = new Array();
4055 var updownGlobalMenuShareEvent = new Array();
4056
4057 // Move up all lines and place first line on last one
4058 updownGlobalMenuTitleTab.push("Move up all lines and place first line on last one")
4059 updownGlobalMenuEventTab.push( function(v, id, optionNumber){
4060 moveMesh("up");
4061 });
4062 updownGlobalMenuIconClassAttributesTab.push("upArrowButtonIcon");
4063 updownGlobalMenuShareEvent.push(true);
4064
4065 // Move down all lines and place last line on first
4066 updownGlobalMenuTitleTab.push("Move down all lines and place last line on first")
4067 updownGlobalMenuEventTab.push( function(v, id, optionNumber){
4068 moveMesh("down");
4069 });
4070 updownGlobalMenuIconClassAttributesTab.push("downArrowButtonIcon");
4071 updownGlobalMenuShareEvent.push(true);
4072
4088 var menuTitleTab = new Array();
4089 var menuEventTab = new Array();
4090 var menuIconClassAttributesTab = new Array();
4091 var menuShareEvent = new Array();
4092
4103 // Filter node through tags and zoom on filtered nodes
4104 menuTitleTab.push("Filter node through tags and zoom on filtered nodes")
4105 menuEventTab.push( function(v,id,optionNumber){
4106
4107 me.savePositions();
4108 // Variable for the magnifyingGlass function
4109 var ratio =spread.Y/spread.X;
4110 var initSpread = spread;
4111
4112 if(v==true) {
4113 var numOfFilter= 0;
4114
4115 $('header').css({height : 250 /*GLOBALCSS ?*/, width : htmlPrimaryParent.css("width")});
4116 _allowDragAndDrop = false;
4117
4118 // Creation of the search bar
4119 $('header').append("<div id=search></div>");
4120 $("#search").css({ //GLOBALCSS
4121 position :"fixed",
4122 top : 0 ,
4123 left : parseInt($(me.menu.getHtmlMenuSelector()).css("width")), // +100/* .split("px")[0] */ ,
4124 height : 100,
4125 width : 800,
4126 backgroundColor : "black",
4127 fontSize : 50,
4128 color : "white"
4129 });
4130
4131 $("#search").append("<label for=filter>Filter: </label>").append("<input id=filter type=text>").css({
4132 position : "fixed" ,
4133 top : 210,
4134 left : parseInt($(me.menu.getHtmlMenuSelector()).css("width")),
4135 zIndex : 131
4136 });
4137 $("#filter").css({
4138 top : 205,
4139 left : parseInt($(me.menu.getHtmlMenuSelector()).css("width")),
4140 height : 80,
4141 width : 800,
4142 fontSize : 70,
4143 zIndex : 131
4144
4145 });
4146 $('filter').draggable();
4147 // Add a button to clean the legend
4148 $('header').append("<div id=brush class=brushButtonIcon></div>");
4149 $("#brush").css({ // GLOBALCSS !
4150 position : "fixed",
4151 height : 200,
4152 width : 200,
4153 top : 0,
4154 left : parseInt($(me.menu.getHtmlMenuSelector()).css("width")),
4155 zIndex : 802,
4156 });
4157 var left_ = parseInt($(me.menu.getHtmlMenuSelector()).css("width")) + parseInt($('#brush').css("width"));
4158 //var width_ = parseInt($('header').css("width"))-left_-50;
4159 var width_ = window.innerWidth - left_;
4160
4161 // Creation of the div $(#blackboard) containing the legend
4162 $('header').append("<div id=blackboard></div>");
4163 $("#blackboard").css({ // GLOBALCSS ?
4164 position :"fixed",
4165 height : "200px" ,
4166 width : width_,
4167 top : 0,
4168 left : left_,
4169 zIndex : 149,
4170 display : "flex",/* flexDirection: "column", */
4171 flexWrap: "wrap"/* , marginTop : 20 */});
4172
4173
4174
4175
4176 // Autocomplete : see https://jqueryui.com/autocomplete/ for details
4177 $( "#search" ).off("autocompleteselect").on( "autocompleteselect", function( event, ui ) {
4178
4179 document.getElementById("filter").value = ui.item.value;
4180 });
4181
4182 // Set user interaction
4183 $("#search").off("tap focusin").on("tap focusin",
4184
4185 function(){
4186
4187 $("#search").off("keydown").on({
4188
4189 keydown : function(e){ // TO DO : replace with keypresses ?
4190 $('#internal_warning').remove();
4191 if(e.keyCode == 13) {
4192 var nodeZoomTab = new Array();
4193 var text_ = $('#filter').val();
4194 // Substitution if the user writes "&&" or "&&&" instead of "&", or spaces
4195 text_=text_.replace('&&','&').replace('&&','&').replace(' ','');
4196 var textTab = text_.split("&"); // Builds a tab with the different tags or filters
4197 var e=0;
4198
4199 for(e=0;e<textTab.length;e++) {
4200 text_=textTab[e];
4201 var nodesbis=nodesById;
4202 var w=0;
4203
4204 if(appliedFilters.indexOf(text_)==-1) {
4205 // TO DO : study influence of nodes/nodesbis in the loops ?
4206 // TO DO : what happens when too many filters ?
4207 for(O in nodesbis) {
4208 if(me.hasTag(nodesbis[O],text_)) {
4209 nodeZoomTab.push(nodesById[O]);
4210 me.switchLocation(nodesbis[O],nodesByLoc[w],false,true);
4211 nodesbis[O].getHtmlNode().css({
4212 opacity : 1
4213 });
4214 nodesbis[O].getStickers().addSticker(text_,colorFilterStickersTab[numOfFilter],true);
4215 w++;
4216 }
4217 }
4218
4219 if(w>0) { // At least one node fits
4220 $("#blackboard").append('<div id='+text_+' >'+text_+'</div>');
4221 //console.log(text_);
4222 $("#"+text_).css({ // GLOBALCSS
4223 width : width_/colorFilterStickersTab.length,
4224 height : 100,
4225 fontSize : 100,
4226 border : 25,
4227 backgroundColor : colorFilterStickersTab[numOfFilter]
4228 });
4229 numOfFilter++;
4230 } else {
4231 $("#blackboard").append('<div id=internal_warning class="legend-warning">Filter not found on those tiles</div>');
4232 }
4233
4234 var filtered = w;
4235 while(w<nodesByLoc.length) {
4236 nodesByLoc[w].getHtmlNode().css({
4237 opacity : 0.5
4238 });
4239 w++;
4240 }
4241
4242 appliedFilters.push(text_);
4243 $('.stickers_zone').css("visibility", "visible");
4244
4245 // To zoom on filtered nodes
4246 // Disabled by Yacouba because there were too many filtered nodes through some queries
4247 // TO DO : find an upper bound to zoom on the nodes if there are not so many nodes
4248 // if(filtered<4) // more complex, should take into account how many nodes are filtered
4249 // with each filter
4250 /* $("#"+text_).on('dblclick',function(){
4251
4252 me.magnifyingGlass(nodeZoomTab,ratio,initSpread);
4253
4254 }); */
4255
4256 } else {
4257
4258 }
4259 }
4260
4261 // Load the nodes provided by the search which are outside the screen and not yet loaded
4262 // depends on "chargeAllContentOnStart" and "distance_from_the_bottom_for_loading")
4263 if(chargeAllContentOnStart==false) {
4264 me.computeNumColumns();
4265 for(O in nodesById ){
4266 node = nodesById[O];
4267 if( node.getLoadedStatus() == false && mesh.locationProvider(node.getIdLocation()).getY()<window.innerHeight ) {
4268 //console.log(node.getmLocation().getnX());
4269 ratio=mesh.loadContent(node.getId());
4270 node.setLoadedStatus(true);
4271 }
4272 }
4273 }
4274 }
4275 }
4276
4277
4278 });
4279 });
4280 $("#search").off("focusout").on({
4281 focusout : function(){
4282
4283 $("#search").off('keydown');
4284
4285 }
4286 });
4287
4288
4289 $( "#filter" ).autocomplete({
4290
4291 source: suggestion_list
4292
4293 });
4294
4295 $('#brush').off("click").on({
4296
4297 click : function() {
4298 var buffer=0;
4299
4300 while(appliedFilters.length>0) {
4301 buffer=appliedFilters.pop();
4302
4303 // for(O in nodesById) {
4304 // nodesById[O].removeElementFromNodeTagList(buffer);
4305 // }
4306
4307 numOfFilter--;
4308 }
4309
4310 $('#blackboard').children().remove();
4311
4312 for (O in nodesByLoc)
4313 if (nodesByLoc[O].getNodeInViewportStatus()) {
4314 nodesByLoc[O].sub('stickers_').css("visibility", "hidden");
4315 nodesByLoc[O].sub('').css({
4316 opacity : 1
4317 });
4318 }
4319 }
4320
4321 });
4322 // Replace icons
4323 $('#'+id+'option'+optionNumber).attr('class',$('#'+id+'option'+optionNumber).attr('class').replace('searchButtonIcon','closeSearchButtonIcon'));
4324 } else {
4325 $("#brush").click();
4326 $('#blackboard').remove();
4327 $("#filter").remove();
4328 $("filter").remove();
4329 $("#search").remove();
4330 $("#brush").remove();
4331 $('#'+id+'option'+optionNumber).attr('class',$('#'+id+'option'+optionNumber).attr('class').replace('closeSearchButtonIcon','searchButtonIcon'));
4332
4333 }
4334 });
4335
4336 menuIconClassAttributesTab.push("searchButtonIcon");
4337 menuShareEvent.push(false)
4338
4339 // /** Share selection to other participants in session. */
4340 // menuTitleTab.push("Share selection")
4341 // menuEventTab.push( function(v,id,optionNumber){
4342
4343 // $('#'+id+'option'+optionNumber).removeClass('selectionButtonIcon').addClass('closeSelectionButtonIcon');
4344 // var listSelectionIds = [];
4345 // var listSelectionTiles=me.getSelectedNodes()
4346 // for(O in listSelectionTiles) {
4347 // listSelectionIds.push(listSelectionTiles[O].getId());
4348 // }
4349 // console.log("share_Selection",listSelectionIds);
4350 // var cdata ={"room":my_session, "Selection": "["+listSelectionIds.toString()+"]" }
4351 // socket.emit("share_Selection", cdata);
4352
4353 // $('#'+id+'option'+optionNumber).removeClass('closeSelectionButtonIcon').addClass('selectionButtonIcon');
4354 // });
4355 // menuIconClassAttributesTab.push("selectionButtonIcon");
4356 // menuShareEvent.push(false);
4357
4359 menuTitleTab.push("Clear selection")
4360 menuEventTab.push( function(v,id,optionNumber){
4361
4362 $('#'+id+'option'+optionNumber).removeClass('clearSelectionButtonIcon').addClass('closeClearSelectionButtonIcon');
4363 for(O in nodesById) {
4364 nodesById[O].updateSelectedStatus(false);
4365 }
4366 me.setZoomSelection(false);
4367 me.resetNodesToZoom();
4368 $('#'+id+'option'+optionNumber).removeClass('closeClearSelectionButtonIcon').addClass('clearSelectionButtonIcon');
4369 addBlink($('#'+id+'option'+optionNumber));
4370 });
4371 menuIconClassAttributesTab.push("clearSelectionButtonIcon");
4372 menuShareEvent.push(true);
4373
4375 var nextList=[];
4376 var IntervalClearSelection=100;
4377 var IntervalCloseTagMenu=100;
4378 var IntervalCloseTagButton=100;
4379 var IntervalSelectOffStickers=100;
4380 var IntervalShareSelection=100;
4381 var IntervalAddNextTag=300;
4382 var IntervalCloseSelectTag=100;
4383 var IntervalSelectionToTag=100;
4384 var IntervalApplyToTag=200;
4385 var IntervalcheckCloseSelectTag=100;
4386 var IntervalCloseSelect=100;
4387 var IntervalAlignTag=100;
4388 var IntervalCloseAll=300;
4389
4390 menuTitleTab.push("Show next tiles.")
4391 menuEventTab.push( function(v,id,optionNumber){
4392
4393 $('#'+id+'option' + optionNumber).removeClass('nextTilesButtonIcon').addClass('closeNextTilesButtonIcon');
4394
4395 if ($('#'+globalTagsList[0]).position() == undefined)
4396 $('.tagsGlobalMenuButtonIcon').click()
4397
4398 me.setSelectTags(true);
4399 $('.clearSelectionButtonIcon').click();
4400
4401 if (nextList.length == 0) {
4402 var numberOff=$('.Off').length;
4403 var numberOn=$('.On').length;
4404 // Select next "Off" tiles with max number "On" or "Off" if it is lower
4405 var numberToView=Math.min(numberOn,numberOff)
4406 }
4407
4408 // All functions for this page salection
4409 // to AddOnTagsPage
4410 funApplyNewTag_CloseMenuButtonIcon=function(newtag) {
4411 var checkApplyNewTag = setInterval(function() {
4412 if ( $('.'+newtag).length > 0 ) {
4413 clearInterval(checkApplyNewTag);
4414 $('.closeSelectTagMenuButtonIcon').click();
4415 }
4416 }, IntervalApplyToTag)
4417 }
4418
4419 funEndselectionToTag_taglegendclick=function(newtag) {
4420 var checkEndselectionToTag = setInterval(function() {
4421 if ( $('.closeSelectionToTagButtonIcon').length) {
4422 clearInterval(checkEndselectionToTag);
4423 $('#tag-legend>#'+newtag).click();
4424 funApplyNewTag_CloseMenuButtonIcon(newtag);
4425 }
4426 }, IntervalSelectionToTag)
4427 }
4428
4429 funEndaddPageTag_selectionToTagButtonIcon = function(newtag) {
4430 var checkEndaddPageTag = setInterval(function() {
4431 if (receive_Add_Tag) {
4432 clearInterval(checkEndaddPageTag);
4433 addBlink($('.selectionToTagButtonIcon'));
4434 $('.selectionToTagButtonIcon').click()
4435 funEndselectionToTag_taglegendclick(newtag);
4436 }
4437 }, IntervalAddNextTag)
4438 }
4439
4440 funCloseSelectTag_emitnewTag = function(page) {
4441 var checkCloseSelectTag = setInterval(function() {
4442 if ($('.selectTagButtonIcon').length) {
4443 clearInterval(checkCloseSelectTag);
4444 var newtag="Page"+page;
4445 console.log("New On page ", newtag);
4446 emit_newTag(id+'option'+optionNumber,newtag);
4447
4448 funEndaddPageTag_selectionToTagButtonIcon(newtag)
4449 }
4450 }, IntervalCloseSelectTag)
4451 }
4452
4453 funEndshareSelectionOn_closeSelectTag = function(page) {
4454 var checkEndshareSelectionOn = setInterval(function() {
4455 if (receive_deploy_Selection) {
4456 clearInterval(checkEndshareSelectionOn);
4457
4458 addBlink($('.closeSelectTagButtonIcon'));
4459 $('.closeSelectTagButtonIcon').click();
4460
4461 funCloseSelectTag_emitnewTag(page);
4462 }
4463 }, IntervalShareSelection)
4464 }
4465
4466 funEndselectOnStickers_listSelectionIds = function(page) {
4467 var checkEndselectOnStickers= setInterval(function() {
4468 if ( me.getSelectedNodes().length > 0) {
4469 clearInterval(checkEndselectOnStickers);
4470
4471 var selectedNodes=me.getSelectedNodes().filter(node=>{if (node.getNodeTagList().indexOf("On") > -1) return node});
4472
4473 addBlink($('.closeSelectTagButtonIcon'))
4474 me.setSelectTags(false);
4475
4476 var listSelectionIds = [];
4477 var listSelectionTiles=me.getSelectedNodes();
4478 for(O in listSelectionTiles) {
4479 listSelectionIds.push(listSelectionTiles[O].getId());
4480 }
4481 //console.log("share_Selection",listSelectionIds);
4482 receive_deploy_Selection=false;
4483 var cdata ={"room":my_session, "Selection": "["+listSelectionIds.toString()+"]" }
4484 socket.emit("share_Selection", cdata);
4485
4486 funEndshareSelectionOn_closeSelectTag(page);
4487 }
4488 }, IntervalSelectOffStickers)
4489 }
4490
4491 funselectTagButton_taglegendOn = function(page) {
4492 var checkselectTagButton = setInterval(function() {
4493 if ($('.closeSelectTagButtonIcon').length) {
4494 clearInterval(checkselectTagButton);
4495
4496 $('#tag-legend>#On').click();
4497 addBlink($('#tag-legend>#On'));
4498 console.log("Selection On");
4499
4500 funEndselectOnStickers_listSelectionIds(page);
4501 }
4502 }, IntervalCloseTagButton)
4503 }
4504
4505 funselectTagMenu_selectTagButtonIcon = function(page) {
4506 var checkselectTagMenu = setInterval(function() {
4507 if ($('.closeSelectTagMenuButtonIcon').length) {
4508 clearInterval(checkselectTagMenu);
4509 if ($('.closeSelectTagButtonIcon').length == 0)
4510 $('.selectTagButtonIcon').click();
4511
4512 funselectTagButton_taglegendOn(page);
4513 }
4514 }, IntervalCloseTagMenu)
4515 }
4516
4517 funAddOnTagsPage = function(page) {
4518 var checkEndcloseTagsGlobalMenu=setInterval(function() {
4519 if ($('.closeTagsGlobalMenuButtonIcon').length ) {
4520 clearInterval(checkEndcloseTagsGlobalMenu);
4521
4522 if ($('.closeSelectTagMenuButtonIcon').length == 0)
4523 $('.selectTagMenuButtonIcon').click();
4524 $('.clearSelectionButtonIcon').click()
4525 addBlink($('.clearSelectionButtonIcon'));
4526
4527 funselectTagMenu_selectTagButtonIcon(page);
4528 }
4529 }, IntervalClearSelection)
4530 }
4531
4532 //funAddOnTagsPage(nextList.length);
4533
4534 //
4535 // All functions for Next page iteration
4536 //
4537 funCloseAll = function() {
4538 var checkCloseAll = setInterval(function() {
4539 if ( EndOfGroupping) {
4540 clearInterval(checkCloseAll);
4541 // HowTo/NeedTo Wait for click on new tag here ?
4542 $('.closeAlignTagButtonIcon').click();
4543 $('.clearSelectionButtonIcon').click();
4544 }
4545 }, IntervalCloseAll)
4546 }
4547
4548 funEndalignTag = function(newtag) {
4549 var checkEndalignTag = setInterval(function() {
4550 if ( $('.closeAlignTagButtonIcon').length ) {
4551 clearInterval(checkEndalignTag);
4552 EndOfGroupping=false;
4553 $('#tag-legend>#'+newtag).click();
4554
4555 funCloseAll();
4556 $('#'+id+'option'+optionNumber).removeClass('closeNextTilesButtonIcon').addClass('nextTilesButtonIcon');
4557
4558 }
4559 }, IntervalAlignTag)
4560 }
4561
4562 funCloseSelect = function(newtag) {
4563 var checkCloseSelect = setInterval(function() {
4564 if ( $('.selectTagMenuButtonIcon').length ) {
4565 clearInterval(checkCloseSelect);
4566 $('.alignTagButtonIcon').click();
4567 addBlink($('.alignTagButtonIcon'));
4568
4569 funEndalignTag(newtag);
4570 }
4571 }, IntervalCloseSelect)
4572 }
4573
4574 //,funnext
4575 funApplyNewTag = function(newtag) {
4576 var checkApplyNewTag = setInterval(function() {
4577 if ( $('.'+newtag).length > 0 ) {
4578 clearInterval(checkApplyNewTag);
4579 $('.closeSelectTagMenuButtonIcon').click();
4580
4581 funCloseSelect(newtag);
4582 }
4583 }, IntervalApplyToTag)
4584 }
4585
4586 funEndselectionToTag = function(newtag) {
4587 var checkEndselectionToTag = setInterval(function() {
4588 if ( $('.closeSelectionToTagButtonIcon').length) {
4589 clearInterval(checkEndselectionToTag);
4590 $('#tag-legend>#'+newtag).click();
4591
4592 funApplyNewTag(newtag);
4593 }
4594 }, IntervalSelectionToTag)
4595 }
4596
4597 funEndaddNextTag = function(newtag) {
4598 var checkEndaddNextTag = setInterval(function() {
4599 if (receive_Add_Tag) {
4600 clearInterval(checkEndaddNextTag);
4601 addBlink($('.selectionToTagButtonIcon'));
4602 $('.selectionToTagButtonIcon').click()
4603
4604 funEndselectionToTag(newtag);
4605 }
4606 }, IntervalAddNextTag)
4607 }
4608
4609 funCloseSelectTag = function(newtag) {
4610 var checkCloseSelectTag = setInterval(function() {
4611 if ($('.selectTagButtonIcon').length) {
4612 clearInterval(checkCloseSelectTag);
4613 var newtag="Next"+nextList.length;
4614 nextList.push(newtag);
4615 console.log("Next add New Tag ", newtag);
4616 emit_newTag(id+'option'+optionNumber,newtag);
4617
4618 funEndaddNextTag(newtag)
4619 }
4620 }, IntervalCloseSelectTag)
4621 }
4622
4623 funEndshareSelectionOff = function() {
4624 var checkEndshareSelectionOff = setInterval(function() {
4625 if (receive_deploy_Selection) {
4626 clearInterval(checkEndshareSelectionOff);
4627
4628 addBlink($('.closeSelectTagButtonIcon'));
4629 $('.closeSelectTagButtonIcon').click();
4630
4631 funCloseSelectTag();
4632 }
4633 }, IntervalShareSelection)
4634 }
4635
4636 funEndselectOffStickers = function() {
4637 var checkEndselectOffStickers = setInterval(function() {
4638 if ( me.getSelectedNodes().length > 0) {
4639 clearInterval(checkEndselectOffStickers);
4640
4641 // Correction from previous Next selection and still Off tiles.
4642 //var selectedNodes= me.getSelectedNodes();
4643 //for (O in selectedNodes) { var node=selectedNodes[O]; console.log(node.getNodeTagList()) }
4644 //var selectedNodes= me.getSelectedNodes(); selectedNodes.filter(node=>{ console.log("Off" in node.getNodeTagList()); if ("Off" in node.getNodeTagList()) node })
4645 var selectedNodes=me.getSelectedNodes().filter(node=>{if (node.getNodeTagList().indexOf("Off") > -1) return node});
4646 //.slice(0,numberToView);
4647
4648 addBlink($('.selectTagButtonIcon'))
4649 me.setSelectTags(false);
4650
4651 var listSelectionIds = [];
4652 var listSelectionTiles=me.getSelectedNodes();
4653 for(O in listSelectionTiles) {
4654 listSelectionIds.push(listSelectionTiles[O].getId());
4655 }
4656 //console.log("share_Selection",listSelectionIds);
4657 receive_deploy_Selection=false;
4658 var cdata ={"room":my_session, "Selection": "["+listSelectionIds.toString()+"]" }
4659 socket.emit("share_Selection", cdata);
4660
4661
4662 funEndshareSelectionOff();
4663 }
4664 }, IntervalSelectOffStickers)
4665 }
4666
4667 funselectTagButton = function() {
4668 var checkselectTagButton = setInterval(function() {
4669 if ($('.closeSelectTagButtonIcon').length) {
4670 clearInterval(checkselectTagButton);
4671
4672 if (nextList.length < 1) {
4673 //funAddOnTagsPage(0);
4674 $('#tag-legend>#Off').click();
4675 addBlink($('#tag-legend>#Off'));
4676 console.log("Selection Off");
4677 } else {
4678 //funAddOnTagsPage(nextList.length);
4679 var oldtag="Next"+(nextList.length-1);
4680 // sans les On ! ou intersection oldtag et Off actuel
4681 $('#tag-legend>#'+oldtag).click();
4682 addBlink($('#tag-legend>#'+oldtag));
4683 console.log("Selection "+oldtag);
4684 }
4685
4686 funEndselectOffStickers();
4687 }
4688 }, IntervalCloseTagButton)
4689 }
4690
4691 funselectTagMenu = function() {
4692 var checkselectTagMenu = setInterval(function() {
4693 if ($('.closeSelectTagMenuButtonIcon').length) {
4694 clearInterval(checkselectTagMenu);
4695 if ($('.closeSelectTagButtonIcon').length == 0)
4696 $('.selectTagButtonIcon').click();
4697
4698 funselectTagButton();
4699 }
4700 }, IntervalCloseTagMenu)
4701 }
4702
4703 funEndcloseTagsGlobalMenu = function() {
4704 var checkEndcloseTagsGlobalMenu = setInterval(function() {
4705 if ($('.closeTagsGlobalMenuButtonIcon').length ) {
4706 clearInterval(checkEndcloseTagsGlobalMenu);
4707
4708 // We can't click on SelectTagMenu and .tagsMenuSelectButton
4709 // because nodes tagged off are not identically distributed to all clients.
4710 // Then we use here internal function setSelectTags and share_Selection after.
4711 if ($('.closeSelectTagMenuButtonIcon').length == 0)
4712 $('.selectTagMenuButtonIcon').click();
4713 $('.clearSelectionButtonIcon').click()
4714 addBlink($('.clearSelectionButtonIcon'));
4715
4716 //funAddOnTagsPage(nextList.length)
4717
4718 //funnext.pop()()
4719 funselectTagMenu();
4720 }
4721 }, IntervalClearSelection)
4722 }
4723
4724 // List of call functions for show Next tiles
4725 funnext=new Array(funEndalignTag,funCloseSelect);
4726
4727 // Run first node for show Next tiles
4728 funEndcloseTagsGlobalMenu();
4729 });
4730 menuIconClassAttributesTab.push("nextTilesButtonIcon");
4731 menuShareEvent.push(false);
4732
4734 menuTitleTab.push("Show rotate button")
4735 menuEventTab.push( ( function(){
4736
4737 return function(v, id, optionNumber){
4738 if (v==true) {
4739 $('.rotate').show();
4740 $('#'+id+'option'+optionNumber).removeClass('RotateButtonIcon').addClass('closeRotateButtonIcon');
4741 } else {
4742 $('.rotate').hide();
4743 $('#'+id+'option'+optionNumber).removeClass("closeRotateButtonIcon").addClass("RotateButtonIcon");
4744
4745 }
4746 };
4747
4748 })());
4749
4750 menuIconClassAttributesTab.push("RotateButtonIcon");
4751 menuShareEvent.push(false);
4752
4753
4758
4759 // Refresh all nodes
4760 menuTitleTab.push("Refresh all nodes")
4761 menuEventTab.push( function (v){
4762 if (v==true) {
4763 refreshNodes();
4764 } else {
4765 refreshNodes();
4766 }
4767 });
4768
4769 menuIconClassAttributesTab.push("refreshButtonIcon");
4770 menuShareEvent.push(true);
4771
4774 // Tag menu
4775 menuTitleTab.push("Tag menu")
4776 menuEventTab.push( function(v, id, optionNumber){
4777 if (v == true) {
4778 for (O in nodesByLoc) {
4779 if (nodesByLoc[O].getNodeInViewportStatus()) {
4780 nodesByLoc[O].sub('hitbox').off("click");
4781 if (!!configBehaviour.moveOnMenuOption) {
4782 nodesByLoc[O].sub('').off();
4783 }
4784 nodesByLoc[O].sub('hitbox').on("click", clickHBTag);
4785 }
4786 }
4787 menuTags.css("visibility", "visible");
4788 // Legend :
4789 var left_ = Math.max(parseInt($(me.menu.getHtmlMenuSelector()).css("width")),
4790 //parseInt($(me.menu.getHtmlMenuSelector()).css("width")) +
4791 parseInt($(me.tagMenu.getHtmlMenuSelector()).css("width"))); // To adapt with the menu in the corner
4792 try {
4793 var width_= parseInt($('#home').position().left)-250 -left_;
4794 } catch(err) {
4795 var width_= parseInt($('header').css('width')) - left_ -600 /*- parseInt($('body').prop("scrollwidth"))*/; // 600 is for the three buttons on the right
4796 }
4797
4798 var tmp = document.getElementById("tag-legend");
4799 if (tmp == null) {
4800 // Init tag-legend
4801 menuTags.append('<div id=tag-legend class=legend scrollable="yes"></div>');
4802
4803 $('#tag-legend').css({//GLOBALCSS
4804 position : "relative",
4805 height : 200,
4806 width : width_,
4807 top : 0,
4808 left : left_,
4809 display : "flex",
4810 flexWrap : "wrap",
4811 zIndex : 149
4812 });
4813 // Add notif zone (bottom of the screen?)
4814 $('body').append('<div id=tag-notif class=tag-notif></div>');
4815 $('#tag-notif').text("click on an icon then a color to use tags.");
4816 } else {
4817 $('#tag-legend').show();
4818 $('#tag-notif').show();
4819 $('.stickers_zone').css("visibility", "visible");
4820
4821 }
4822
4823 // Pre-load some tags (depending on configuration)
4824 if (typeof(computedTagsList) == "undefined") {
4825 computedTagsList = [];
4826 }
4827 if (computedTagsList.length == 0) {
4828 if (configTagsBehaviour.showAll) {
4829 computedTagsList = globalTagsList.sort();
4830 }
4831 else if (configTagsBehaviour.selectionMethod =="frequency") {
4832 // Calculations on the dico
4833 var tagHisto = new Array ();
4834 var temp = 0;
4835 for (var k=0;k<globalTagsList.length;k++) {
4836 for (var i=0;i<me.getCardinal();i++) {
4837 if(me.hasTag(nodesByLoc[i],globalTagsList[k])) {
4838 temp +=1;
4839 }
4840 }
4841 tagHisto[k]=temp;
4842 temp = 0;
4843 }
4844 var maxValues = new Array();
4845 var index = -1;
4846 for(var k=0;k<Math.min(configTagsBehaviour.numOfTagsToShow, globalTagsList.length);k++) {
4847 maxValues[k] = $.inArray(Math.max.apply(null, tagHisto), tagHisto);
4848 computedTagsList.push(globalTagsList[maxValues[k]]);
4849
4850 tagHisto[maxValues[k]] = - (k+1); // To register the used indices
4851 if (computedTagsList.length <= colorTagStickersTab.length) {
4852 attributedTagsColorsArray[computedTagsList[computedTagsList.length-1]] = colorTagStickersTab[computedTagsList.length-1];
4853 } else if (computedTagsList.length<(colorTagStickersTab.length + colorFilterStickersTab.length-2)) {
4854 attributedTagsColorsArray[computedTagsList[computedTagsList.length-1]] =
4855 colorFilterStickersTab[computedTagsList.lengthk-colorTagStickersTab.length];
4856 } else {
4857 attributedTagsColorsArray[computedTagsList[computedTagsList.length-1]] =
4858 "rgb("+Math.floor(Math.random()*255) + ", " + Math.floor(Math.random()*255)+ ", " + Math.floor(Math.random()*255)+")";
4859 }
4860 for(O in nodesByLoc) {
4861 if(me.hasTag(nodesByLoc[O], computedTagsList[k]) ) {
4862 var color = attributedTagsColorsArray[computedTagsList[k]];
4863 nodesByLoc[O].getStickers().addSticker(computedTagsList[k], false, color);
4864 }
4865
4866 }
4867 }
4868 }
4869 else if(configTagsBehaviour.selectionMethod == "alphabet") {
4870 computedTagsList = globalTagsList.slice(0, configTagsBehaviour.numOfTagsToShow);
4871 }
4872
4873 // Build legend
4874 if ($('#tag-legend').children(".tag").length<computedTagsList.length) {
4875 // Check length: if a tag is already in the legend, there’s no need in putting it up again (TO DO: refine the test…)
4876 for(k=0;k<computedTagsList.length;k++) {
4877
4878 var ck=computedTagsList[k]
4879 if (ck=="") {
4880 break;
4881 }
4882 if ( ck in globalFloatingTags ) {
4883 var symb=globalFloatingTags[ck]["symb"]
4884 $('#tag-legend').append('<div id =' + ck + ' class=tag>'+ck +" "+ symb +'</div>');
4885 ComputedTag=$('#' + ck);
4886 ComputedTag.css({
4887 'background': 'linear-gradient(to right,'+globalFloatingTags[ck]["cm"]+','+globalFloatingTags[ck]["cM"]+')'
4888 });
4889 } else {
4890 $('#tag-legend').append('<div id =' + ck + ' class=tag>' + ck + '</div>');
4891 ComputedTag=$('#' + ck);
4892 ComputedTag.css({
4893 backgroundColor : attributedTagsColorsArray[ck]
4894 });
4895 }
4896 if ( ComputedTag.position().top+ComputedTag.height() > $("#tag-legend").height() ) {
4897 $("#tag-legend").css({height: ComputedTag.position().top + ComputedTag.height()+10});
4898 }
4899
4900 }
4901 for (O in nodesByLoc)
4902 if (nodesByLoc[O].getNodeInViewportStatus())
4903 nodesByLoc[O].sub('stickers_').show();
4904 }
4905 TagHeight=($("#tag-legend").height());
4906 if ( my_user != "Anonymous" ) {
4907 TopPP=TagHeight;
4908 htmlPrimaryParent.css("marginTop",TopPP+"px");;
4909 ppot=TopPP;
4910 }
4911
4912 // for debugging : add tag with initial grid order
4913 if (debugPos) {
4914 for(O in nodesByLoc) {
4915 me.AddNewTag("pos"+nodesByLoc[O].getId());
4916 nodesByLoc[O].getStickers().addSticker("pos"+nodesByLoc[O].getId(), attributedTagsColorsArray["pos"+nodesByLoc[O].getId()],false);
4917 nodesByLoc[O].addElementToNodeTagList("pos"+nodesByLoc[O].getId());
4918 }
4919 }
4920 for(O in nodesByLoc) {
4921 nodesByLoc[O].getStickers().updateStickers();
4922 }
4923 }
4924 $('.stickers_zone').css("visibility", "visible");
4925
4926
4927
4928 $('.tag').off("click").on({
4929 click : clickTagInLegend
4930 });
4931
4932 $('.sticker').off("click").on({
4933 click : clickSticker
4934 });
4935
4936 $('#'+id+'option'+optionNumber).removeClass('tagsGlobalMenuButtonIcon').addClass('closeTagsGlobalMenuButtonIcon');
4937
4938 } else {
4939 me.tagMenu.closeAllOptions();
4940 menuTags.css("visibility", "hidden");
4941 $('#tag-notif').hide();
4942 // for (var i=0; i<tagMenuEventTab.length;i++) {
4943 // var tmp_class = $('#'+id+'option'+i).attr("class").match(/\w+ButtonIcon/g)[0];
4944 // var isNotClosed = tmp_class.match("close");
4945 // if (isNotClosed) {
4946 // var new_class = tmp_class.replace("close", "");
4947 // new_class = new_class[0].toLowerCase() + new_class.slice(1);
4948 // menuTags.children('#'+id+'option'+i).removeClass(tmp_class).addClass(new_class);
4949 // }
4950 // }
4951 //console.log(menuTags.children());
4952 $('.stickers_zone').css("visibility", "hidden");
4953 $('#tag-legend').hide();
4954 if(currentSelectedTag != "") {
4955 $('#'+currentSelectedTag).css("outlineStyle", "none");
4956 }
4957 currentSelectedTag = "";
4958 $('#new-tag').remove();
4959 $('#add-tag').remove();
4960 //??
4961 $('new-tag').remove();
4962 me.meshEventReStart();
4963
4964 // If numerous tags, restore initial grid/legend position
4965 // if (computedTagsList.length>10) {
4966
4967 // TopPP=($("#tag-legend").height())
4968 // htmlPrimaryParent.css("marginTop",TopPP+"px");
4969 // //htmlPrimaryParent.css("margin", "0px 0px 0px 300px");
4970 // }
4971 $('#'+id+'option'+optionNumber).removeClass('closeTagsGlobalMenuButtonIcon').addClass('tagsGlobalMenuButtonIcon');
4972
4973 }
4974 });
4975 menuIconClassAttributesTab.push('tagsGlobalMenuButtonIcon');
4976 menuShareEvent.push(true)
4977
4978 // Action menu
4979
4980 menuTitleTab.push("All action functions Menu")
4981 menuEventTab.push( function(v, id, optionNumber){
4982 if(v==true) {
4983 menuActionGlobal
4984 .css("top", (function(){
4985 return menuGlobal.position()["top"]+$('.actionGlobalMenuButtonIcon').position()["top"];
4986 })() )
4987 .css("left",menuGlobal.position()["left"]+menuGlobal.width())
4988 .css("visibility", "visible");
4989
4990 BlockDragAndDrop();
4991
4992 for (O in nodesByLoc)
4993 if (nodesByLoc[O].getNodeInViewportStatus()) {
4994 nodesByLoc[O].sub('').off();
4995 nodesByLoc[O].sub('hitbox').off("click").on("click", clickHBSelect);
4996 nodesByLoc[O].sub('hitbox').off("mouseenter");
4997 }
4998 me.resetNodesToZoom();
4999 me.setZoomSelection(true);
5000 $('#'+id+'option'+optionNumber).removeClass('actionGlobalMenuButtonIcon').addClass('closeActionGlobalMenuButtonIcon');
5001 } else {
5002 me.actionGlobalMenu.closeAllOptions();
5003 menuActionGlobal.css("visibility", "hidden");
5004 me.setZoomSelection(false);
5005 for (O in nodesByLoc)
5006 if (nodesByLoc[O].getNodeInViewportStatus())
5007 nodesByLoc[O].sub('hitbox').off("click").on("click", clickHB);
5008 $('#'+id+'option'+optionNumber).removeClass('closeActionGlobalMenuButtonIcon').addClass('actionGlobalMenuButtonIcon');
5009 }
5010 });
5011 menuIconClassAttributesTab.push("actionGlobalMenuButtonIcon");
5012 menuShareEvent.push(false);
5013
5014 // Zoom Global Menu
5015 menuTitleTab.push("All zoom functions Menu")
5016 menuEventTab.push( function(v, id, optionNumber){
5017 if(v==true) {
5018 menuZoomGlobal
5019 .css("top", (function(){
5020 return menuGlobal.position()["top"]+$('.zoomGlobalMenuButtonIcon').position()["top"];
5021 })() )
5022 .css("left",menuGlobal.position()["left"]+menuGlobal.width())
5023 .css("visibility", "visible");
5024 $('#'+id+'option'+optionNumber).removeClass('zoomGlobalMenuButtonIcon').addClass('closeZoomGlobalMenuButtonIcon');
5025 } else {
5026 me.zoomGlobalMenu.closeAllOptions();
5027 menuZoomGlobal.css("visibility", "hidden");
5028 $('#'+id+'option'+optionNumber).removeClass('closeZoomGlobalMenuButtonIcon').addClass('zoomGlobalMenuButtonIcon');
5029 }
5030 });
5031 menuIconClassAttributesTab.push("zoomGlobalMenuButtonIcon");
5032 menuShareEvent.push(false);
5033
5034 // Management menu
5035
5036 menuTitleTab.push("All management functions Menu")
5037 menuEventTab.push( function(v, id, optionNumber){
5038 if(v==true) {
5039 menuManagementGlobal
5040 .css("top",menuGlobal.position()["top"]+menuGlobal.height())
5041 .css("left",menuGlobal.position()["left"])
5042 .css("visibility", "visible");
5043 $('#'+id+'option'+optionNumber).removeClass('managementGlobalMenuButtonIcon').addClass('closeManagementGlobalMenuButtonIcon');
5044 } else {
5045 me.managementGlobalMenu.closeAllOptions();
5046 menuManagementGlobal.css("visibility", "hidden");
5047 $('#'+id+'option'+optionNumber).removeClass('closeManagementGlobalMenuButtonIcon').addClass('managementGlobalMenuButtonIcon');
5048 }
5049 });
5050 menuIconClassAttributesTab.push("managementGlobalMenuButtonIcon");
5051 menuShareEvent.push(false);
5052
5053 // State of tiles Menu
5054 menuTitleTab.push("All state of tile functions")
5055 menuEventTab.push( function(v, id, optionNumber){
5056 if(v==true) {
5057 menuStateGlobal
5058 .css("top", (function(){
5059 return menuGlobal.position()["top"]+$('.stateGlobalMenuButtonIcon').position()["top"];
5060 })() )
5061 .css("left",menuGlobal.position()["left"]+menuGlobal.width())
5062 .css("visibility", "visible");
5063 $('#'+id+'option'+optionNumber).removeClass('stateGlobalMenuButtonIcon').addClass('closeStateGlobalMenuButtonIcon');
5064 } else {
5065 // We want to keep state info on demand.
5066 //me.stateGlobalMenu.closeAllOptions();
5067 menuStateGlobal.css("visibility", "hidden");
5068 $('#'+id+'option'+optionNumber).removeClass('closeStateGlobalMenuButtonIcon').addClass('stateGlobalMenuButtonIcon');
5069 }
5070 });
5071 menuIconClassAttributesTab.push("stateGlobalMenuButtonIcon");
5072 menuShareEvent.push(false);
5073
5074 // Display/Hide the node menu
5075 menuTitleTab.push("Display/Hide the node menu")
5076 menuEventTab.push( function(v,id,optionNumber){
5077 if (executeAtEndComplete) {
5078 if(v==true) {
5079 if (!!configBehaviour.moveOnNodeMenuOption) {
5080 for (O in nodesByLoc)
5081 if (nodesByLoc[O].getNodeInViewportStatus()) {
5082 nodesByLoc[O].sub('').off();
5083 nodesByLoc[O].sub('hitbox').off();
5084 }
5085 }
5086
5087 for (O in nodesByLoc)
5088 if (nodesByLoc[O].getNodeInViewportStatus())
5089 nodesByLoc[O].getHtmlNode().children(".nodemenu").css({visibility : "visible"});
5090
5091 $('#'+id+'option'+optionNumber).attr('class',$('#'+id+'option'+optionNumber).attr('class').replace('nodeMenuButton','closeNodeMenuButton'));
5092 } else {
5093 var nodeId =0;
5094
5095 for (O in nodesByLoc)
5096 if (nodesByLoc[O].getNodeInViewportStatus()) {
5097 var p =0 ;
5098 var mymenu=nodesByLoc[O].getNodeMenu();
5099 for(p=0;p<mymenu.getEventSelectedTab().length;p++) {
5100 if(mymenu.getEventSelectedTab()[p]==true) {
5101 $("#menu"+mymenu.getId()+">#option"+p).click();
5102 //console.log("obscure if condition in NodeMenu");
5103 }
5104 }
5105 $("#menu"+mymenu.getId()).css({visibility : "hidden"});
5106 }
5107
5108
5109 me.meshEventReStart();
5110 $('#'+id+'option'+optionNumber).attr('class',$('#'+id+'option'+optionNumber).attr('class').replace('closeNodeMenuButton','nodeMenuButton'));
5111 }
5112 }
5113 });
5114 menuIconClassAttributesTab.push("nodeMenuButtonIcon");
5115 menuShareEvent.push(true);
5116
5117 // Cancel Global Menu
5118
5119 menuTitleTab.push("cancel/redo Menu")
5120 menuEventTab.push( function(v, id, optionNumber){
5121 if(v==true) {
5122 menuCancelGlobal
5123 .css("top", (function(){
5124 return menuGlobal.position()["top"]+$('.cancelGlobalMenuButtonIcon').position()["top"];
5125 })() )
5126 .css("left",menuGlobal.position()["left"]+menuGlobal.width())
5127 .css("visibility", "visible");
5128 $('#'+id+'option'+optionNumber).removeClass('cancelGlobalMenuButtonIcon').addClass('closeCancelGlobalMenuButtonIcon');
5129 } else {
5130 me.cancelGlobalMenu.closeAllOptions();
5131 menuCancelGlobal.css("visibility", "hidden");
5132 $('#'+id+'option'+optionNumber).removeClass('closeCancelGlobalMenuButtonIcon').addClass('cancelGlobalMenuButtonIcon');
5133 }
5134 });
5135 menuIconClassAttributesTab.push("cancelGlobalMenuButtonIcon");
5136 menuShareEvent.push(false);
5137
5138 // Updown Global Menu
5139
5140 menuTitleTab.push("up/down Menu")
5141 menuEventTab.push( function(v, id, optionNumber){
5142 if(v==true) {
5143 menuUpdownGlobal
5144 .css("top", (function(){
5145 return menuGlobal.position()["top"]+$('.updownGlobalMenuButtonIcon').position()["top"];
5146 })() )
5147 .css("left",menuGlobal.position()["left"]+menuGlobal.width())
5148 .css("visibility", "visible");
5149 $('#'+id+'option'+optionNumber).removeClass('updownGlobalMenuButtonIcon').addClass('closeUpdownGlobalMenuButtonIcon');
5150 } else {
5151 menuUpdownGlobal.css("visibility", "hidden");
5152 $('#'+id+'option'+optionNumber).removeClass('closeUpdownGlobalMenuButtonIcon').addClass('updownGlobalMenuButtonIcon');
5153 }
5154 });
5155 menuIconClassAttributesTab.push("updownGlobalMenuButtonIcon");
5156 menuShareEvent.push(false);
5157
5161
5162 this.menu = new Menu("Global",$('header'),menuTitleTab,menuEventTab,menuIconClassAttributesTab,menuShareEvent,{
5163 position : "fixed",
5164 top : $('#notifications').height(),
5165 left : 0,
5166 visible : "visible",
5167 classN : "super",
5168 height : 200, //GLOBAL + TO DO : adapt it to the size of the screen
5169 width : 200,
5170 rightMargin :0,
5171 orientation : "V"
5172 });
5173 menuGlobal=$('#menuGlobal');
5174
5175 subMenusGlobal=Array();
5176
5177 this.tagMenu = new Menu("tagsGlobal", $('header'), tagMenuTitleTab, tagMenuEventTab, tagMenuIconClassAttributesTab, tagMenuShareEvent,{
5178 position : "fixed",
5179 top : 0,
5180 left : parseInt($(me.menu.getHtmlMenuSelector()).css('width')), //parseInt(window.innerWidth) - tagMenuEventTab.length*200,
5181 visible : 'hidden',
5182 classN : 'tag',
5183 height : 200,
5184 width : 200,
5185 rightMargin :0,
5186 //borderStyle : "solid",
5187 //borderWidth : "5px",
5188 //borderColor : "green",
5189 orientation : "H",
5190 zIndex : 149
5191
5192 });
5193 menuTags=$('#menutagsGlobal');
5194 subMenusGlobal.push(this.tagMenu);
5195
5196 this.actionGlobalMenu = new Menu("actionGlobal", $('header'), actionGlobalMenuTitleTab, actionGlobalMenuEventTab, actionGlobalMenuIconClassAttributesTab, actionGlobalMenuShareEvent,{
5197 position : "fixed",
5198 top : parseInt($(me.menu.getHtmlMenuSelector()).css('height')),
5199 left : parseInt($(me.menu.getHtmlMenuSelector()).css('width')),
5200 visible : 'hidden',
5201 classN : 'action',
5202 height : 200,
5203 width : 200,
5204 rightMargin :0,
5205 backgroundColor: "rgba(0, 0, 0, 0.6)",
5206 //borderStyle : "solid",
5207 //borderWidth : "5px",
5208 //borderColor : "green",
5209 orientation : "H",
5210 zIndex : 149
5211
5212 });
5213 menuActionGlobal=$('#menuactionGlobal');
5214 subMenusGlobal.push(this.actionGlobalMenu);
5215
5216 this.zoomGlobalMenu = new Menu("zoomGlobal", $('header'), zoomGlobalMenuTitleTab, zoomGlobalMenuEventTab, zoomGlobalMenuIconClassAttributesTab, zoomGlobalMenuShareEvent,{
5217 position : "fixed",
5218 top : parseInt($(me.menu.getHtmlMenuSelector()).css('height')),
5219 left : parseInt($(me.menu.getHtmlMenuSelector()).css('width')),
5220 visible : 'hidden',
5221 classN : 'zoom',
5222 height : 200,
5223 width : 200,
5224 rightMargin :0,
5225 backgroundColor: "rgba(0, 0, 0, 0.6)",
5226 //borderStyle : "solid",
5227 //borderWidth : "5px",
5228 //borderColor : "green",
5229 orientation : "H",
5230 zIndex : 149
5231
5232 });
5233 menuZoomGlobal=$('#menuzoomGlobal');
5234 subMenusGlobal.push(this.zoomGlobalMenu);
5235
5236 this.managementGlobalMenu = new Menu("managementGlobal", $('header'), managementGlobalMenuTitleTab, managementGlobalMenuEventTab, managementGlobalMenuIconClassAttributesTab, managementGlobalMenuShareEvent,{
5237 position : "fixed",
5238 top : parseInt($(me.menu.getHtmlMenuSelector()).css('height')),
5239 left : parseInt($(me.menu.getHtmlMenuSelector()).css('left')),
5240 visible : 'hidden',
5241 classN : 'manage',
5242 height : 200,
5243 width : 200,
5244 rightMargin :0,
5245 backgroundColor: "rgba(0, 0, 0, 0.6)",
5246 //borderStyle : "solid",
5247 //borderWidth : "5px",
5248 //borderColor : "green",
5249 orientation : "V",
5250 zIndex : 149
5251
5252 });
5253 menuManagementGlobal=$('#menumanagementGlobal');
5254 subMenusGlobal.push(this.managementGlobalMenu);
5255
5256 this.stateGlobalMenu = new Menu("stateGlobal", $('header'), stateGlobalMenuTitleTab, stateGlobalMenuEventTab, stateGlobalMenuIconClassAttributesTab, stateGlobalMenuShareEvent,{
5257 position : "fixed",
5258 top : parseInt($(me.menu.getHtmlMenuSelector()).css('height')),
5259 left : parseInt($(me.menu.getHtmlMenuSelector()).css('width')),
5260 visible : 'hidden',
5261 classN : 'state',
5262 height : 200,
5263 width : 200,
5264 rightMargin :0,
5265 backgroundColor: "rgba(0, 0, 0, 0.6)",
5266 //borderStyle : "solid",
5267 //borderWidth : "5px",
5268 //borderColor : "green",
5269 orientation : "H",
5270 zIndex : 149
5271
5272 });
5273 menuStateGlobal=$('#menustateGlobal');
5274 subMenusGlobal.push(this.stateGlobalMenu);
5275
5276 this.cancelGlobalMenu = new Menu("cancelGlobal", $('header'), cancelGlobalMenuTitleTab, cancelGlobalMenuEventTab, cancelGlobalMenuIconClassAttributesTab, cancelGlobalMenuShareEvent,{
5277 position : "fixed",
5278 top : parseInt($(me.menu.getHtmlMenuSelector()).css('height')),
5279 left : parseInt($(me.menu.getHtmlMenuSelector()).css('width')),
5280 visible : 'hidden',
5281 classN : 'cancel',
5282 height : 200,
5283 width : 200,
5284 rightMargin :0,
5285 backgroundColor: "rgba(0, 0, 0, 0.6)",
5286 //borderStyle : "solid",
5287 //borderWidth : "5px",
5288 //borderColor : "green",
5289 orientation : "H",
5290 zIndex : 149
5291
5292 });
5293 menuCancelGlobal=$('#menucancelGlobal');
5294 subMenusGlobal.push(this.cancelGlobalMenu);
5295
5296 this.updownGlobalMenu = new Menu("updownGlobal", $('header'), updownGlobalMenuTitleTab, updownGlobalMenuEventTab, updownGlobalMenuIconClassAttributesTab, updownGlobalMenuShareEvent,{
5297 position : "fixed",
5298 top : parseInt($(me.menu.getHtmlMenuSelector()).css('height')),
5299 left : parseInt($(me.menu.getHtmlMenuSelector()).css('width')),
5300 visible : 'hidden',
5301 classN : 'updown',
5302 height : 200,
5303 width : 200,
5304 rightMargin :0,
5305 backgroundColor: "rgba(0, 0, 0, 0.6)",
5306 //borderStyle : "solid",
5307 //borderWidth : "5px",
5308 //borderColor : "green",
5309 orientation : "H",
5310 zIndex : 149
5311
5312 });
5313 menuUpdownGlobal=$('#menuupdownGlobal');
5314 subMenusGlobal.push(this.updownGlobalMenu);
5315
5316 var menutagsGlobaljs=document.getElementById("menutagsGlobal");
5317 this.drawMenu = new Menu("Draw", $('header'), drawMenuTitleTab, drawMenuEventTab, drawMenuIconClassAttributesTab, drawMenuShareEvent,{
5318 position : "fixed",
5319 top : 0,
5320 left : menutagsGlobaljs.offsetLeft+$('#menutagsGlobal').width(),
5321 visible : 'hidden',
5322 classN : 'draw',
5323 height : 200,
5324 width : 200,
5325 rightMargin :0,
5326 //borderStyle : "solid",
5327 //borderWidth : "5px",
5328 //borderColor : "green",
5329 orientation : "H",
5330 zIndex : 801
5331
5332 });
5333 menuDraw=$('#menuDraw');
5334
5335 this.zoomMenu = new Menu("Zoom", $('header'), zoomMenuTitleTab, zoomMenuEventTab, zoomMenuIconClassAttributesTab, zoomMenuShareEvent, {
5336 position : "fixed",
5337 top : 0,
5338 left : menutagsGlobaljs.offsetLeft+$('#menutagsGlobal').width(),
5339 visible : 'hidden',
5340 classN : 'zoomAction',
5341 height : 200,
5342 width : 200,
5343 rightMargin :0,
5344 //borderStyle : "solid",
5345 //borderWidth : "5px",
5346 //borderColor : "green",
5347 orientation : "H",
5348 zIndex : 801
5349
5350 });
5351 menuZoom=$('#menuZoom');
5352
5353 this.MSMenu = new Menu("MS", $('header'), MSMenuTitleTab, MSMenuEventTab, MSMenuIconClassAttributesTab, MSMenuShareEvent, {
5354 position : "fixed",
5355 top : 0,
5356 left : menutagsGlobaljs.offsetLeft+$('#menutagsGlobal').width(),
5357 visible : 'hidden',
5358 classN : 'masterslave',
5359 height : 200,
5360 width : 200,
5361 rightMargin :0,
5362 //borderStyle : "solid",
5363 //borderWidth : "5px",
5364 //borderColor : "green",
5365 orientation : "H",
5366 zIndex : 801
5367
5368 });
5369 menuMS=$('#menuMS');
5370
5371 this.tagAlignOrderTagsMenu = new Menu("AlignOrderTags", $('header'), tagAlignOrderTagsMenuTitleTab, tagAlignOrderTagsMenuEventTab, tagAlignOrderTagsMenuIconClassAttributesTab, tagAlignOrderTagsMenuShareEvent,{
5372 position : "fixed",
5373 top : 100,
5374 left : parseInt($(me.menu.getHtmlMenuSelector()).css('width')), //parseInt(window.innerWidth) - tagMenuEventTab.length*200,
5375 visible : 'hidden',
5376 classN : 'tagalignOrdertags',
5377 height : 200,
5378 width : 200,
5379 rightMargin :0,
5380 backgroundColor: "rgba(0, 0, 0, 0.5)",
5381 //borderStyle : "solid",
5382 //borderWidth : "5px",
5383 //borderColor : "green",
5384 orientation : "V",
5385 zIndex : 150
5386
5387 });
5388 menuAlignOrderTags=$('#menuAlignOrderTags');
5389
5390 this.tagHideTagsMenu = new Menu("HideTags", $('header'), tagHideTagsMenuTitleTab, tagHideTagsMenuEventTab, tagHideTagsMenuIconClassAttributesTab, tagHideTagsMenuShareEvent,{
5391 position : "fixed",
5392 top : 100,
5393 left : parseInt($(me.menu.getHtmlMenuSelector()).css('width')), //parseInt(window.innerWidth) - tagMenuEventTab.length*200,
5394 visible : 'hidden',
5395 classN : 'taghidetags',
5396 height : 200,
5397 width : 200,
5398 rightMargin :0,
5399 backgroundColor: "rgba(0, 0, 0, 0.5)",
5400 //borderStyle : "solid",
5401 //borderWidth : "5px",
5402 //borderColor : "green",
5403 orientation : "V",
5404 zIndex : 150
5405
5406 });
5407 menuHideTags=$('#menuHideTags');
5408
5409 this.tagSelectionMenu = new Menu("SelectionTags", $('header'), tagSelectionMenuTitleTab, tagSelectionMenuEventTab, tagSelectionMenuIconClassAttributesTab, tagSelectionMenuShareEvent,{
5410 position : "fixed",
5411 top : 100,
5412 left : parseInt($(me.menu.getHtmlMenuSelector()).css('width')), //parseInt(window.innerWidth) - tagMenuEventTab.length*200,
5413 visible : 'hidden',
5414 classN : 'tagselect',
5415 height : 200,
5416 width : 200,
5417 rightMargin :0,
5418 backgroundColor: "rgba(0, 0, 0, 0.5)",
5419 //borderStyle : "solid",
5420 //borderWidth : "5px",
5421 //borderColor : "green",
5422 orientation : "V",
5423 zIndex : 150
5424
5425 });
5426 menuSelectionTags=$('#menuSelectionTags');
5427
5428 this.tagManagementMenu = new Menu("ManagementTags", $('header'), tagManagementMenuTitleTab, tagManagementMenuEventTab, tagManagementMenuIconClassAttributesTab, tagManagementMenuShareEvent,{
5429 position : "fixed",
5430 top : 100,
5431 left : parseInt($(me.menu.getHtmlMenuSelector()).css('width')), //parseInt(window.innerWidth) - tagMenuEventTab.length*200,
5432 visible : 'hidden',
5433 classN : 'tagmanage',
5434 height : 200,
5435 width : 200,
5436 rightMargin :0,
5437 backgroundColor: "rgba(0, 0, 0, 0.5)",
5438 //borderStyle : "solid",
5439 //borderWidth : "5px",
5440 //borderColor : "green",
5441 orientation : "V",
5442 zIndex : 150
5443
5444 });
5445 menuManagementTags=$('#menuManagementTags');
5446
5447 //******select column and line******//
5448
5449 //--getter
5450 this.getcolumnSelected = function(){
5451 return columnSelected;
5452 };
5453
5455
5456 //--getter
5457 this.getlineSelected = function(){
5458 return lineSelected;
5459 };
5460
5461 //--setter
5462 this.setcolumnSelected = function(number){
5463 columnSelected = number;
5464 };
5465
5467
5468 //--setter
5469 this.setlineSelected = function(number){
5470 lineSelected = number ;
5471 };
5472
5473 //******columns******//
5474
5476
5477 //--getter
5478 this.getNumOfColumns = function(){
5479 return numOfColumns;
5480 };
5481
5483
5484 //--setter
5485 this.setNodes = function(){
5486 return nodesById;
5487 };
5488
5489 //******heighttable and widthtable******//
5490
5491 //--getter
5492 this.getHeightTab = function(){
5493 return heightTab;
5494 };
5495
5496 //--getter
5497 this.getWidthTab = function(){
5498 return widthTab;
5499 };
5500
5501
5502 //--setter
5503 this.setHeightTab = function(index,value){
5504 heightTab[index]=value;
5505 };
5506
5507 //--setter
5508 this.setWidthTab = function(index,value){
5509 widthTab[index]=value;
5510 };
5511
5512
5513 //--update, apply to all elements the changement of spread
5514 this.updateSpread = ( function(){
5515 var initialSpread=spread;
5516 var scale =1;
5517 //console.log(initialSpread, newSpread);
5518 return function(newSpread,id){
5519
5520
5521 var scaleX=(newSpread.X/ initialSpread.X);
5522 var scaleY=(newSpread.Y/ initialSpread.Y);
5523 scale = (scaleX + scaleY)/2;
5524 //console.log("scale", scaleX, scaleY, scale);
5525 if(typeof id == 'undefined' || typeof id != 'number' || (id < 0) || !(id < nodeCardinal)) {
5526 spread=newSpread;
5527 for(O in nodesById) {
5528 nodesById[O].updateHW(spread.Y,spread.X);
5529
5530 }
5531 $('.selection').css({height : spread.Y, width : spread.X});
5532 $('iframe').height(spread.Y).width(spread.X);
5533 // $('iframe').css( '-webkit-transform', "scale("+scaleX+","+ scaleY +")");
5534 // $('iframe').css( '-moz-transform', "scale("+scaleX+","+ scaleY +")");
5535 // OnOff with just spread.Y ?
5536 $('.onoff').css("height",parseInt(spread.Y*0.1)).css("width",parseInt(spread.Y*0.1)).css("left",-parseInt(spread.Y*0.1)).css("z-index", 161);
5537 $('.hitbox').css("height", parseInt(spread.Y*0.9)).css("top",parseInt(spread.Y*0.1));
5538 $('.info').css("font-size", Math.min(configBehaviour.maxInfoFontSize,parseInt(configBehaviour.defaultInfoFontSize*scale)));
5539
5540 for(O in nodesById) {
5541 if(ColumnStyle=="static") // Why are the two parts of this condition the same?!
5542
5543 {
5544 //var marginleft = (parseInt($('#'+nodesById[O].getId()).css("width"))-widthTab[nodesById[O].getId()]*scale)/2;
5545 var node=nodesById[O];
5546 me.setLocation(node,node.getIdLocation(),false).done(updateNode(node));
5547 //var margintop = (parseInt($('#'+nodesById[O].getId()).css("height"))-heightTab[nodesById[O].getId()]*scale)/2;
5548
5549 $('#iframe'+nodesById[O].getId()).css({marginTop : 0 , marginLeft : 0 });
5550 }
5551 else // "dynamic" ColumnStyle
5552 {
5553 //var marginleft = (parseInt($('#'+nodesById[O].getId()).css("width"))-widthTab[nodesById[O].getId()]*scale)/2;
5554 var node=nodesById[O];
5555 me.setLocation(node,node.getIdLocation(),false).done(updateNode(node));
5556 //var margintop = (parseInt($('#'+nodesById[O].getId()).css("height"))-heightTab[nodesById[O].getId()]*scale)/2;
5557 $('#iframe'+nodesById[O].getId()).css({marginTop : 0,marginLeft : 0 });
5558 }
5559
5560
5561 }
5562 $('.stickers_zone').css("left", spread.X);
5563 //console.log($('.info').css("font-size"));
5564 configBehaviour.defaultInfoFontSize = $('.info').css("font-size");
5565 //console.log(configBehaviour.defaultInfoFontSize);
5566
5567 } else {
5568 spread=newSpread;
5569
5570 nodesById["node"+id].updateHW(spread.Y,spread.X);
5571
5572 // ?? Global functions for update spread for one tile ??
5573 $('.selection').css({height : spread.Y, width : spread.X});
5574 $('iframe').height(spread.Y).width(spread.X);
5575 //$('iframe').css( '-webkit-transform', "scale("+scaleX+","+ scaleY +")");
5576 //$('iframe').css( '-moz-transform', "scale("+scaleX+","+ scaleY +")");
5577 $('.onoff').css("height",parseInt(spread.Y*0.1)).css("width",parseInt(spread.Y*0.1)).css("left",-parseInt(spread.Y*0.1));
5578 $('.hitbox').css("height", parseInt(spread.Y*0.9)).css("top",parseInt(spread.Y*0.1));
5579 //console.log(parseInt($('.info').css("font-size")));
5580 $('.info').css("font-size", Math.min(configBehaviour.maxInfoFontSize,parseInt(configBehaviour.defaultInfoFontSize*scale)));
5581 //console.log(parseInt($('.info').css("font-size")));
5582
5583 if(ColumnStyle=="static") {
5584 var marginleft = (parseInt($('#'+nodesById["node"+id].getId()).css("width"))-widthTab[nodesById["node"+id].getId()]*scale)/2;
5585 var node=nodesById["node"+id];
5586 me.setLocation(node,node.getIdLocation(),false).done(updateNode(node));
5587 var margintop = (parseInt($('#'+nodesById["node"+id].getId()).css("height"))-heightTab[nodesById["node"+id].getId()]*scale)/2;
5588
5589 $('#iframe'+nodesById["node"+id].getId()).css({marginTop : 0 , smarginLeft : 0 });
5590
5591 } else {
5592 var marginleft = (parseInt($('#'+nodesById["node"+id].getId()).css("width"))-widthTab[nodesById["node"+id].getId()]*scale)/2;
5593 var node=nodesById["node"+id];
5594 me.setLocation(node,node.getIdLocation(),false).done(updateNode(node));
5595 var margintop = (parseInt($('#'+nodesById["node"+id].getId()).css("height"))-heightTab[nodesById["node"+id].getId()]*scale)/2;
5596 $('#iframe'+nodesById["node"+id].getId()).css({marginTop : margintop,marginLeft : marginleft });
5597 }
5598 $('.stickers_zone').css("left", spread.X);
5599 //console.log($('.info').css("font-size"));
5600 configBehaviour.defaultInfoFontSize = $('.info').css("font-size");
5601 //console.log(configBehaviour.defaultInfoFontSize);
5602 }
5603 };
5604
5605
5606 })();
5607
5608 this.getSpread = function(){
5609 return spread;
5610 };
5611
5612 //******cardinal******//
5613
5614 //--getter
5615 this.getCardinal = function(){
5616 return nodeCardinal;
5617 };
5618
5619 //--setter
5620 this.setCardinal = function(n){
5621 nodeCardinal = n;
5622 };
5623
5624
5625 //******nodes******//
5626
5628
5629 //--getter
5630 this.getNode = function(id){
5631 return nodesById["node"+id];
5632 };
5633
5635
5636 //--getter
5637 this.getNodes = function(){
5638 return nodesById;
5639 };
5640
5641
5643
5644 //--getter
5645 this.getNodesByLoc = function(){
5646 return nodesByLoc;
5647 };
5648
5649 //--setter
5650 setNodesByLoc = function(idLocation,node){
5651 nodesByLoc[idLocation]=node;
5652 };
5653
5654
5655
5656 //******location******//
5657
5658 var widthScreen = htmlPrimaryParent.width();
5659 this.computeNumColumns = function(newNumOfColumns){
5660 // Test if newNumOfColumns has been given as parameter
5661 newNumOfColumns = newNumOfColumns || false;
5662
5663 if (newNumOfColumns !=false) {
5664 numOfColumns = Math.min(newNumOfColumns, maxNumOfColumns);
5665 } else {
5666 widthScreen = htmlPrimaryParent.width();
5667 //console.log("processing num of columns from spread and screen size");
5668 numOfColumns =
5669 Math.min(
5670 Math.max(
5671 Math.floor((widthScreen-parseInt($(me.menu.getHtmlMenuSelector()).css("width")))/(spread.X+borderSize)),
5672 1),
5673 maxNumOfColumns);
5674 }
5675 };
5676
5679
5680 //--find node mlocation
5681 this.mlocationProvider = function(node_idLocation){
5682 var nX =node_idLocation%numOfColumns ;
5683 var nY = Math.floor(node_idLocation/numOfColumns);
5684 return (new MLocation(nX,nY));
5685 };
5686
5690
5691 var ppol=primaryparent.offsetLeft;
5692 var ppot=$(".main-legend-zone").height();
5693 //primaryparent.offsetTop;
5694 //--find node location
5695 this.locationProvider = function(node_idLocation){
5696
5697 var temp = me.mlocationProvider(node_idLocation);
5698 var nX =temp.getnX();
5699 var nY =temp.getnY();
5700 // var x = nX*(spread.X+gapBetweenColumns)+ (nX)*borderSize+htmlPrimaryParent.offset().left;
5701 var x = nX*(spread.X + gapBetweenColumns + borderSize)+ppol;
5702 //var y = nY*(spread.Y+gapBetweenLines)+ (nY)*borderSize+htmlPrimaryParent.offset().top;
5703 var y = nY*(spread.Y + gapBetweenLines + borderSize)+ppot;
5704 return (new Location(x,y));
5705 };
5706
5707 //--find all node location
5708 this.globalLocationProvider = function(){
5709
5710 for(O in nodesById) {
5711 if(!$('#' + nodesById[O].getId()).hasClass("transparentNode")) { // Transparent nodes have sometimes to remain superposed
5712 nodesById[O].setLocation(me.locationProvider(nodesById[O].getIdLocation()),false);
5713 setNodesByLoc(nodesById[O].getIdLocation(),nodesById[O]);
5714 } else {
5715 $('#'+nodesById[O].getId()).css("z-index", 899);
5716 //console.log("getting new z-index at ", $('#'+nodesById[O].getId()).css("z-index"));
5717 }
5718
5719 }
5720
5721 };
5722
5723
5724 // Change location of a node and update nodesByLoc table
5725 this.setLocation = function(node, IdLoc, boolAnimation, animationSpeed) {
5726 boolAnimation = boolAnimation || false;
5727 animationSpeed = animationSpeed || configBehaviour.animationSpeed;
5728 node.setLocation(me.locationProvider(IdLoc),boolAnimation,animationSpeed);
5729 setNodesByLoc(node.getIdLocation(),node);
5730 return $.Deferred().resolve();
5731 }
5732 var updateNode = function(node) {
5733 // Force wait end of animation to asynchronusly detect
5734 if (node.getNodeInViewportStatus()) {
5735 node.setOnOffStatus(true);
5736 node.updateUrl();
5737 }
5738 }
5739
5740 //--Switch position between two nodes
5741
5742 this.switchLocation = function(node1,node2,boolAnimation,boolSavePosition, boolBlockMove){
5743 boolBlockMove = boolBlockMove || false;
5744 if(boolSavePosition==true)
5745 me.savePositions(boolBlockMove);
5746 var tampon = node1.getIdLocation();
5747
5748 node1.setIdLocation(node2.getIdLocation());
5749 node2.setIdLocation(tampon);
5750
5751 //if($('#' + node1.getId()).hasClass("transparentNode") || $('#' + ListMoveNodes[NodeM-1]).hasClass("transparentNode")) {
5752 //console.log("don’t swap, transparent");
5753 //} else {
5754
5755 node1.setLocation(me.locationProvider(node1.getIdLocation()),boolAnimation,configBehaviour.animationSpeed);
5756 node2.setLocation(me.locationProvider(node2.getIdLocation()),boolAnimation,configBehaviour.animationSpeed);
5757
5758
5759 setNodesByLoc(node2.getIdLocation(),node2);
5760 setNodesByLoc(node1.getIdLocation(),node1);
5761 node1.setNodeInViewportStatus();
5762 node2.setNodeInViewportStatus();
5763 }
5764
5765 //--A node gets the position of another one
5766 // and all the columns will be shifted and all the lines to the initial position
5767 this.switchLocationShiftColumnLine = function(node1,node2,boolAnimation,boolSavePosition){
5768
5769 var lineDrag =this.mlocationProvider( node1.getIdLocation() ).getnY();
5770 var columnDrag =this.mlocationProvider( node1.getIdLocation() ).getnX();
5771 var lineDrop =this.mlocationProvider( node2.getIdLocation() ).getnY();
5772 var columnDrop =this.mlocationProvider( node2.getIdLocation() ).getnX();
5773
5774 this.setlineSelected( lineDrop );
5775 this.setcolumnSelected( columnDrop );
5776
5777 //console.log(lineDrag, lineDrop, columnDrag, columnDrop);
5778
5779
5780 // Ces commentaires rappellent que l'on devra optimiser l'algo
5781 // si les images à déplacer sont lourdes (Jupyter, vnc ?)
5782 // SaveNode=node1;
5783 // node1.setJsonDataUrl("")
5784 // node1.setLoadedStatus(false)
5785 // me.loadContent(node1.getId());
5786 // node1.setLoadedStatus(true)
5787
5788 var ListMoveNodes= [];
5789 var nX = [];
5790 var nY = [];
5791
5792 for(O in this.getNodesByLoc()) {
5793 nX[O]=this.mlocationProvider( this.getNodesByLoc()[O].getIdLocation()).getnX();
5794 nY[O]=this.mlocationProvider( this.getNodesByLoc()[O].getIdLocation()).getnY();
5795 }
5796
5797 if ( lineDrag > lineDrop ) {
5798 if ( columnDrag > columnDrop ) {
5799
5800 for(O in this.getNodesByLoc()) {
5801
5802 if (nX[O] == columnDrop && lineDrag > nY[O] && !(nY[O] < lineDrop) ) {
5803 this.getNodesByLoc()[O].getHtmlNode().css({
5804 boxShadow: "0 0 0 10px blue"});//GLOBALCSS
5805 ListMoveNodes.push(this.getNodesByLoc()[O])
5806
5807 } else if ( !(nX[O] < columnDrop) && nY[O] == lineDrag && !(nX[O] > columnDrag) ) {
5808 this.getNodesByLoc()[O].getHtmlNode().css({
5809 boxShadow: "0 0 0 10px red"});//GLOBALCSS
5810 ListMoveNodes.push(this.getNodesByLoc()[O])
5811 }
5812 }
5813
5814 } else {
5815
5816 for(O in this.getNodesByLoc()){
5817 if (nX[O] == columnDrop && lineDrag > nY[O] && !(nY[O] < lineDrop) ) {
5818 this.getNodesByLoc()[O].getHtmlNode().css({
5819 boxShadow: "0 0 0 10px blue"});
5820 ListMoveNodes.push(this.getNodesByLoc()[O])
5821 }
5822 }
5823
5824 ReverseList=[]
5825 for(O in this.getNodesByLoc()) {
5826 if ( !(nX[O] < columnDrag) && nY[O] == lineDrag && !(nX[O] > columnDrop) ) {
5827 this.getNodesByLoc()[O].getHtmlNode().css({
5828 boxShadow: "0 0 0 10px red"});
5829 ReverseList=[this.getNodesByLoc()[O]].concat(ReverseList)
5830 }
5831 }
5832 ListMoveNodes=ListMoveNodes.concat(ReverseList)
5833 }
5834
5835 } else {
5836 //( lineDrag <= lineDrop )
5837 if ( columnDrag > columnDrop ) {
5838
5839 ReverseList=[]
5840 for(O in this.getNodesByLoc()) {
5841 if (nX[O] == columnDrop && (nY[O] > lineDrag) && !(lineDrop < nY[O]) ) {
5842 this.getNodesByLoc()[O].getHtmlNode().css({
5843 boxShadow: "0 0 0 10px blue"});
5844 ReverseList=[this.getNodesByLoc()[O]].concat(ReverseList)
5845 }
5846
5847 }
5848
5849 for(O in this.getNodesByLoc()) {
5850 if ( !(nX[O] < columnDrop) && nY[O] == lineDrag && !(nX[O] > columnDrag) ) {
5851 this.getNodesByLoc()[O].getHtmlNode().css({
5852 boxShadow: "0 0 0 10px red"});
5853 ListMoveNodes.push(this.getNodesByLoc()[O])
5854 }
5855 }
5856 ListMoveNodes=ReverseList.concat(ListMoveNodes)
5857
5858 } else {
5859 //( lineDrag <= lineDrop )
5860 // ( columnDrag <= columnDrop )
5861
5862 ReverseList=[]
5863 for(O in this.getNodesByLoc()) {
5864 if (nX[O] == columnDrop && (nY[O] > lineDrag) && !(lineDrop < nY[O]) ) {
5865 this.getNodesByLoc()[O].getHtmlNode().css({
5866 boxShadow: "0 0 0 10px blue"});
5867 ReverseList=[this.getNodesByLoc()[O]].concat(ReverseList)
5868 }
5869
5870 }
5871
5872 ReverseList2=[]
5873 for(O in this.getNodesByLoc()) {
5874 if ( !(nX[O] < columnDrag) && nY[O] == lineDrag && !(nX[O] > columnDrop) ) {
5875 this.getNodesByLoc()[O].getHtmlNode().css({
5876 boxShadow: "0 0 0 10px blue"});
5877 ReverseList2=[this.getNodesByLoc()[O]].concat(ReverseList2)
5878 }
5879
5880 }
5881 ListMoveNodes=ReverseList.concat(ReverseList2)
5882
5883 }
5884 }
5885
5886 for(NodeM=ListMoveNodes.length-1; NodeM > 0;NodeM--) {
5887 //console.log("swapping nodes : ", node1.getId(), ListMoveNodes[NodeM-1].getId());
5888 node1.setIsMoving(true);
5889 this.switchLocation(node1,ListMoveNodes[NodeM-1],configBehaviour.showAnimationsLineColSwap,true);
5890 ListMoveNodes[NodeM-1].getHtmlNode().css({
5891 boxShadow: ""});
5892 }
5893 node1.getHtmlNode().css({
5894 boxShadow: ""});
5895 node1.updateSelectedStatus(false);
5896
5897 // node1.setJsonDataUrl(SaveNode.getJsonData().url)
5898 // node1.setLoadedStatus(false)
5899 // me.loadContent(node1.getId())
5900 // node1.setLoadedStatus(true)
5901
5902 } // End switchLocationShiftColumnLine
5903
5904
5905 //******selectedNode******//
5906
5907 //--add node on selectedtable
5908 addSelectedNode = function(node){
5909 selectedNodes.push(node);
5910 }
5911
5912 //--remove node on selectedtable
5913 removeSelectedNode = function(node){
5914 selectedNodes.splice(selectedNodes.indexOf(node),1);
5915 };
5916
5917 //--getter node selected status table
5918 this.getSelectedNodes = function(){
5919 return selectedNodes;
5920 };
5921
5922 //******nodesToToggle******//
5923
5924 //--add node to toggle
5925 addNodeToToggle = function(node){
5926 nodesToToggle.push(node);
5927 }
5928
5929 //--remove node to toggle
5930 removeNodeToToggle = function(node){
5931 nodesToToggle.splice(nodesToToggle.indexOf(node),1);
5932 };
5933
5934 //--getter node selected status table
5935 this.getNodesToToggle = function(){
5936 return nodesToToggle;
5937 };
5938
5939 //******Border size******//
5940
5941 //--getter
5942 this.getBorderSize = function(){
5943 return borderSize;
5944 };
5945
5946
5947
5948 //******nodes******//
5949 me.computeNumColumns();
5950
5952 nodesById = ( function(){
5953
5954 var node = [];
5955 var nodes_ = [];
5956 var temp = []; // utility ?
5957
5958 for(i=0;i<nodeCardinal;i++) {
5959 temp = new Location(); // utility ?
5960 node = new Tile(this);
5961 nodes_["node"+node.getId()]=node;
5962 nodesByLoc[node.getIdLocation()]=node;
5963 }
5964 globalTagsList.sort();
5965
5966 return nodes_;
5967 }());
5968
5969
5970 //******nodesOldPosition*******//
5971
5972
5973 this.savePositions = function(boolBlockMove){
5974 boolBlockMove = boolBlockMove || false;
5975
5976 if(stepBack>1) {
5977 while(stepBack > 1) {
5978 stepBack--;
5979 nodesOldPositions.pop();
5980 }
5981 }
5982
5983 var indice = nodesOldPositions.length;
5984
5985 nodesOldPositions[indice] = new Array();
5986
5987 var u = 0;
5988
5989 for(u=0;u<nodesByLoc.length;u++) {
5990 nodesOldPositions[indice][u]=nodesByLoc[u].getId();
5991 }
5992 nodesOldPositions[indice].push(boolBlockMove); // The last element of the layer says if it’s part of a block move or not
5993
5994
5995 };
5996
5997 //******extra method******//
5998
6004 this.hasTag = function(node,word){
6005
6006 if(node.getJsonData().comment.search(word)>-1 || node.getNodeTagList().indexOf(word)>-1)
6007 // Adapted to search in "comment" field of the nodes.js, and in the "nodeTagList" (which can be modified during a session)
6008 return true;
6009 else
6010 return false;
6011
6012 };
6013
6018 this.hasFloatingTag = function(node,word){
6019 return node.getFloatingTag().hasOwnProperty(word)
6020 };
6021
6023 this.changeNodeSize = function(){
6024
6025 var X_ = (parseInt($("body").prop("scrollWidth")))/(maxNumOfColumns);
6026 // To be checked for new version ....
6027 ratio = spread.X/((parseInt($("body").prop("scrollWidth"))-(maxNumOfColumns-1)*gapBetweenColumns- X_)/maxNumOfColumns);
6028 //mesh.updateSpread({X : spread.X/ratio , Y : spread.Y/ratio});
6029 me.computeNumColumns();
6030 };
6031
6033 // Inspired by this.changeNodeSize, may need some adaptations
6034 /*this.changeMenuSize = function(){
6035 var X_ = (parseInt($('body').prop("scrollWidth")))/(maxNumOfColumns);
6036 ratio = spread.X/((parseInt($('body').prop("scrollWidth"))-(maxNumOfColumns - 1)* )) }; */
6037
6038
6039
6041 putOnTop = function(nodeId){
6042
6043 for ( O in nodesById) {
6044 if(!(nodesById[O].getId()==nodeId)) {
6045 putDown(nodesById[O].getId());
6046 } else {
6047 $("#"+nodesById[O].getId()).css("z-index",100);
6048 }
6049 }
6050 };
6052 putDown = function(nodeId){
6053 if($('#'+nodeId).attr("class").match("transparentNode")) {
6054 //console.log("dont put down");
6055 $("#"+nodeId).css("z-index",100);
6056 } else {
6057 $("#"+nodeId).css("z-index",3);
6058 }
6059 };
6060
6062 this.loadContent = ( function(){
6063
6064 var maxH = -1;
6065 var maxW = -1;
6066
6067 return function (nodeId) {
6068 var node = nodesById["node"+nodeId];
6069 var hnode=node.getHtmlNode();
6070 var ratio = 1;
6071 if ($("#iframe"+nodeId).length == 0) {
6072 hnode.append('<iframe id=iframe'+node.getId()+' scrolling = "yes" src="" frameborder=0 height = "'+
6073 hnode[0].clientHeight + 'px" width = "' + hnode[0].clientWidth + 'px" style="display=none"></iframe>');
6074 }
6075 var widthtab = [];
6076 var heighttab =[];
6077
6078 ( function(){
6079
6080 var id=node.getId();
6081 var iframe = $('#iframe'+id);
6082 iframe.onload = function(){
6083 widthtab[id] = this.width;
6084 heighttab[id] = this.height;
6085 mesh.setWidthTab(id,this.width);
6086 mesh.setHeightTab(id,this.height);
6087
6088 if(maxH<heighttab[id] || maxW<widthtab[id]){
6089
6090 if(maxH<heighttab[id])
6091 maxH = heighttab[id];
6092
6093 if(maxW<widthtab[id])
6094 maxW = widthtab[id];
6095
6096 iframe.height(heighttab[id]).width(widthtab[id]).css(zIndex,101 /*marginLeft : marginleft , marginTop : margintop }*/ );
6097 //iframe.attr("src",this.src);
6098 if(ColumnStyle=="static"){
6099 var W = (parseInt($("body").prop("scrollWidth")))/(maxNumOfColumns);
6100 ratio = maxW/((parseInt($("body").prop("scrollWidth"))-(maxNumOfColumns-1)*gapBetweenColumns- W)/maxNumOfColumns);
6101 }
6102 //console.log(ratio);
6103 //mesh.updateSpread({X : maxW/ratio , Y : maxH/ratio});
6104 //mesh.globalLocationProvider();
6105 } else {
6106 iframe.height(heighttab[id]).width(widthtab[id]) /*.css({zIndex:101, marginLeft : marginleft , marginTop : margintop } )*/;
6107 mesh.changeNodeSize();
6108
6109 };
6110
6111 }
6112
6113 node.updateUrl();
6114 //$(".temporaire").remove(); Not used anywhere else in script2 ?!
6115
6116 // We need to return it because on function startLoading only visible nodes will be loaded
6117
6118 } ());
6119
6120 return ratio;
6121
6122 };
6123 })(); // End loadContent
6124
6125 this.loadHitbox = ( function(){ // Load hitboxes (if visible ?) and their behaviour
6126 return function(nodeId) {
6127 //console.log("loadingHB");
6128 var HB = $('#hitbox'+nodeId);
6129 var id = nodeId;
6130 HB.css({
6131 height: spread.Y,
6132 width: 60, // GLOBAL !
6133 left: -60,
6134 zIndex: 102,
6135 position: 'absolute',
6136 });
6137
6138 };
6139 })();
6140
6141 var SetOff = function(id) {
6142 var node=$('#'+id);
6143 var OOF = $('#onoff'+id);
6144 var node2= nodesById["node"+id];
6145 OOF.css('background-color', "red");
6146 node.children("iframe").hide();
6147 node2.setLoadedStatus(false);
6148 }
6149
6150 var SetOn = function(id) {
6151 var node=$('#'+id);
6152 var OOF = $('#onoff'+id);
6153 var node2= nodesById["node"+id];
6154 OOF.css('background-color', "green");
6155 node2.setLoadedStatus(true);
6156 mesh.loadContent(id);
6157 node.children("iframe").show();
6158 node2.updateUrl()
6159 }
6160
6161
6163 this.startLoading = function() {
6164 // Creation of the mesh, loading image data
6165 //waypoints are the object which can detect when a object are entering on screen
6166 // see http://imakewebthings.com/waypoints/ for details
6167 var waypoint = new Array();
6168 var ratio = 1;
6169
6170 if(configBehaviour.showInfoAtLoading) {
6171 for (O in nodesByLoc)
6172 if (nodesByLoc[O].getNodeInViewportStatus())
6173 nodesByLoc[O].getHtmlNode().children(".info").css({visibility : "visible"});
6174 $(".showInfoButtonIcon").removeClass('showInfoButtonIcon').addClass('closeShowInfoButtonIcon');
6175 }
6176
6177 me.computeNumColumns();
6178 for(O in nodesById){
6179
6180 var id = O.replace("node","");
6181 var node = mesh.getNode(id);
6182 var ratio = 1;
6183
6184 if( node.getLoadedStatus() == false &&
6185 node.getNodeInViewportStatus() ) {
6186
6187 ratio=mesh.loadContent(node.getId());
6188 SetOn(id);
6189 mesh.loadHitbox(node.getId());
6190 }
6191 else if(node.getLoadedStatus() == false) {
6192
6193 var id = node.getId();
6194 //remember : http://imakewebthings.com/waypoints/ for details
6195 //#005-2
6196 //offset : parseInt(window.innerHeight) + distance_from_the_bottom_for_loading ,
6197 waypoint[id] = new Waypoint({
6198
6199 offset : 'bottom-in-view' ,
6200 element: document.getElementById(''+node.getId()),
6201
6202 handler: ( function(){
6203
6204 var id = node.getId();
6205 return function(direction) {
6206
6207 ratio = mesh.loadContent(id);
6208 mesh.loadHitbox(id);
6209 waypoint[id].destroy();
6210 node.setLoadedStatus(true);
6211
6212 };
6213
6214 })()
6215 });
6216 }
6217 }
6218
6219 spread = mesh.getSpread();
6220 mesh.updateSpread({X : spread.X/ratio , Y : spread.Y/ratio});
6221
6222 //* Dynamic icons for actionGlobal menu
6223 for ( var TS in json_actions) {
6224 for ( var thisAction in json_actions[TS]) {
6225 var FuncName=json_actions[TS][thisAction][0];
6226 var IconName=json_actions[TS][thisAction][1];
6227 var ButtonDiv=$(".optionfromactionGlobal").filter("."+TS+"_"+IconName+"ButtonIcon")
6228 if (ButtonDiv.children().length == 0) {
6229 ButtonDiv.append('<i class="material-icons" style="position:relative; top:100px; color:'+
6230 $('.'+TS).css("background-color")+'; -moz-transform:scale(8);-webkit-transform:scale(8)">'+
6231 IconName+'</i>')
6232 }
6233 }}
6234
6235 }; // End startLoading
6236
6238 this.meshEventStart = function(){
6239 // Reset events
6240 $('.hitbox').off();
6241 $('.node').off();
6242 $('.qrcode').on({
6243 click : me.clickQRcode
6244 });
6245
6246 _allowDragAndDrop = true;
6247 touchspeed = configBehaviour.touchSpeed; // speed of touch move;
6248
6249 this.meshEventReStart = function(){
6250 setTimeout(function() {
6251 if (touchok)
6252 htmlPrimaryParent.off();
6253
6254 for (O in nodesByLoc) {
6255 if (nodesByLoc[O].getNodeInViewportStatus()) {
6256 nodesByLoc[O].sub('qrcode').off();
6257 nodesByLoc[O].sub('handle').off();
6258 nodesByLoc[O].sub('rotate').off();
6259
6260 nodesByLoc[O].sub('hitbox').off();
6261 nodesByLoc[O].sub('onoff').off();
6262 nodesByLoc[O].sub('').off();
6263 }
6264 }
6265 _allowDragAndDrop = true;
6266
6267 if (touchok)
6268 htmlPrimaryParent.on(touchhandleEvent);
6269
6270 for (O in nodesByLoc) {
6271 if (nodesByLoc[O].getNodeInViewportStatus()) {
6272 nodesByLoc[O].sub('onoff').on(OOFEvent);
6273 nodesByLoc[O].sub('handle').on(handleEvent);
6274 nodesByLoc[O].sub('rotate').on(rotateEvent);
6275 nodesByLoc[O].sub('hitbox').on(HBEvent);
6276 nodesByLoc[O].sub('').on(NodeEvent);
6277 nodesByLoc[O].setLoadedStatus(true);
6278
6279 nodesByLoc[O].sub('qrcode').on({
6280 click : clickQRcode
6281 });
6282 }
6283 }
6284 }, 100);
6285 }
6286
6287 this.setDraggable = function(targetNode_, boolBorder, boolTransparent){
6288 //console.log("in set draggable border "+boolBorder+", transp "+boolTransparent);
6289 if (! $('#' + targetNode_).hasClass("ui-draggable")) {
6290 //console.log("setDraggable "+targetNode_);
6291 $('#'+targetNode_).css("z-index", 999);
6292 $('#handle'+targetNode_).addClass("drag-handle-dragging");
6293 if (boolTransparent) {
6294 console.log("set draggable transp ", boolTransparent);
6295 } else if(boolBorder) {
6296 console.log("set draggable border ", boolBorder);
6297 $('#' + targetNode_).children("iframe").hide(); //attr("src", "about:blank");
6298 $('#' + targetNode_).css("background-color", "transparent");
6299 $('#' + targetNode_).css("border", "10px solid white");
6300 }
6301 putOnTop(targetNode_);
6302 $('#'+targetNode_).draggable();
6303 $('#' + targetNode_).off("mouseleave");
6304 if (parseBool(configBehaviour.moveOnGrid)) {
6305 $('#' + targetNode_).draggable("option", "grid", [spread.X + gapBetweenColumns, spread.Y + configBehaviour.gapBetweenLines]);
6306 }
6307 $('#' + targetNode_).off("mouseup").on("mouseup", function(e){
6308
6309 me.dropNode(targetNode_);
6310 refreshNodes(targetNode_);
6311 me.globalLocationProvider();
6312 //e.stopPropagation(); // Or the "mousedown/mouseup"
6313 });
6314 }
6315
6316
6317 };
6318
6319 this.unsetDraggable = function(targetNode_, boolBorder, boolTransparent){ // Called in "dropNode", not to be used as stand-alone
6320
6321 boolBorder = boolBorder || configBehaviour.moveOnlyABorder;
6322 //console.log("in unset draggable",targetNode_, $('#'+targetNode_).hasClass("ui-draggable"));
6323
6324 boolTransparent = boolTransparent || $('#'+targetNode_).attr("class").match("transparentNode");
6325
6326 if($('#' + targetNode_).hasClass("ui-draggable")) {
6327 $('#' + targetNode_).draggable("destroy");
6328 } else {
6329 //alert("this node wasn't even draggable!'")
6330 //console.log("Warning : node " + targetNode_ + " wasn't draggable");
6331 }
6332 if (boolTransparent) {
6333 $('#'+targetNode_).css("z-index", 899);
6334 //console.log("getting new z-index at ", $('#'+targetNode_).css("z-index"));
6335 } else {
6336 $('#'+targetNode_).css("z-index", 3);
6337 }
6338 if (boolBorder) {
6339 if (nodesByLoc[targetNode_].getLoadedStatus()) {
6340 $('#' + targetNode_).css("background-color", "white");
6341 $('#' + targetNode_).css("border-display", "none");
6342 me.loadContent(targetNode_);
6343 }
6344 }
6345
6346 //$('#hitbox' + targetNode_).css("background-color", "black");
6347 $('#handle'+targetNode_).removeClass("drag-handle-dragging");
6348
6349 //console.log(me.getSelectedNodes());
6350
6351 };
6352
6353 this.dropNode = function(targetNode_){
6354 var node = me.getNode(targetNode_);
6355 //console.log("dropNode "+targetNode_);
6356 node.updateLocFromHtmlNode();
6357 var nodeX = node.getLocation().getX();
6358 var nodeY = node.getLocation().getY();
6359 me.RealdropNode(targetNode_, nodeX, nodeY);
6360 $('#'+targetNode_).addClass("NotSharedAgain");
6361 cdata={"room":my_session, "id":targetNode_, "posX":nodeX , "posY":nodeY };
6362 socket.emit("move_tile", cdata, callback=function(sdata){
6363 //console.log("socket send move_tile", sdata);
6364 });
6365 };
6366
6367 this.RealdropNode = function(targetNode_, newPosX, newPosY){
6368 var node = me.getNode(targetNode_);
6369 //console.log("dropNode "+targetNode_);
6370 node.updateLocFromHtmlNode();
6371 var nodeX = newPosX;
6372 var nodeY = newPosY;
6373 var i = 0;
6374
6375 allocate = false;
6376 for(i = 0 ; i < nodeCardinal ; i++) {
6377 if(i != node.getId()) {
6378 var tmpNodeLoc = nodesById["node" + i].getLocation();
6379 var tmpNodeX = tmpNodeLoc.getX();
6380 var tmpNodeY = tmpNodeLoc.getY();
6381 var v = nodeX - tmpNodeX;
6382 var w = nodeY - tmpNodeY;
6383
6384 if((v>-spread.X/targetSize && w>-spread.Y/targetSize) && (v<spread.X/targetSize && w<spread.Y/targetSize)) {
6385 //console.log("found "+ nodesById["node"+i].getId()+ " -> ("+ $('#' + node.getId()).attr("class")+")");
6386 if($('#'+node.getId()).hasClass("transparentNode")) { // Drop on corresponding tile
6387 me.setLocation(node,tmpNodeLoc);
6388 allocate = true;
6389
6390 } else { // Drop besides the tile
6391 me.switchLocationShiftColumnLine(node,nodesById["node"+i],true,true);
6392 allocate = true;
6393 node.updateSelectedStatus(false);
6394 }
6395 break;
6396 }
6397 }
6398 }
6399
6400 if (allocate == false) { // ie node not dropped, no corresponding tile found
6401 me.setLocation(node,node.getIdLocation(),false,50);
6402 }
6403
6404 };
6405
6406 socket.on('receive_move', function(sdata){
6407 //console.log("receive_move",sdata);
6408
6409 var newPosX = sdata["posX"];
6410 var newPosY = sdata["posY"];
6411 var tileID = parseInt(sdata["id"]);
6412 //console.log("2 receive_move", sdata["session_id"], $('#'+tileID), newPosX, newPosY);
6413 if ( ! $('#'+tileID).hasClass("NotSharedAgain") )
6414 me.RealdropNode(tileID, newPosX, newPosY);
6415 else
6416 $('#'+tileID).removeClass("NotSharedAgain");
6417 });
6418
6419
6420 var dragAndDrop = function(targetNode_){
6421
6422 //console.log("dragAndDrop"+targetNode_);
6423 // Don’t trigger if an option is selected
6424 if (!_allowDragAndDrop) {
6425 $('node').filter('.ui-draggable').draggable("destroy");
6426 //console.log("Don’t move: drag and drop not allowed here");
6427 //return -1;
6428 } else {
6429 var targetNode = targetNode_;
6430 var node = mesh.getNode(targetNode);
6431 var _isNodeTransparent = ($('#' + targetNode).hasClass("transparentNode") == true);
6432 mesh.setDraggable(targetNode, configBehaviour.moveOnlyABorder, _isNodeTransparent);
6433 }
6434 };
6435
6436 // Group tags along a pattern
6437 var groupTags = function(pattern_) {
6438 var Nodes = nodesByLoc;
6439 var NodesByLoc = nodesByLoc;
6440 //console.log("grouping", pattern_);
6441 var w = 0;
6442 for (O in Nodes) {
6443 if (mesh.hasTag(Nodes[O], pattern_)) {
6444 mesh.switchLocation(Nodes[O], NodesByLoc[w], false, true)
6445 }
6446 }
6447 };
6448
6449 // Behaviour when mouse is over a node
6450 var mouseEnterFunction = function () {
6451
6452 var node = mesh.getNode(this.id);
6453 node.updateHtmlNodeState(1);
6454 if ($('node').filter('.ui-draggable').length == 0) { // No draggable nodes to keep on top
6455 putOnTop(node.getId());
6456 var HB=$('#hitbox'+node.getId());
6457 var HBcolor = HB.css('background-color');
6458 if(HBcolor != colorHBselectedRGB && HBcolor != colorHBtoZoomRGB) { // Keep the color only if the node has been selected or zoomed
6459 HB.css("background-color", colorHBonfocus);
6460 }
6461 }
6462 if (_allowDragAndDrop) {
6463 //console.log("from mouseEnterFunction")
6464 //dragAndDrop(this);
6465 } else {
6466 //console.log("Drag and drop not allowed :'(");
6467 }
6468 };
6469
6470 // When the mouse leaves the node : no border anymore, only a change in color on the HB !
6471 var mouseLeaveFunction = function () {
6472 //console.log("mouseLeaveFunction");
6473 for (O in nodesByLoc)
6474 if (nodesByLoc[O].getNodeInViewportStatus()) {
6475 nodesByLoc[O].sub('').off("mouseup");
6476 }
6477 var node = mesh.getNode(this.id);
6478 var HBcolor = $('#hitbox'+node.getId()).css('background-color');
6479 if(HBcolor != colorHBselectedRGB && HBcolor != colorHBtoZoomRGB) { // Keep the color only if the node has been selected or zoomed
6480 $('#hitbox'+node.getId()).css('background-color', colorHBdefault);
6481 }
6482
6483
6484 if(node.getState()==3) { // 3 == drag and drop achieved
6485 node.draggable("destroy")
6486 mesh.loadContent(this.id);
6487 }
6488
6489 node.updateHtmlNodeState(0);
6490 putDown(node.getId());
6491 };
6492
6493 //When a mouse click on a node
6494 // -> First the node is colored in red
6495 // -> the node color back to normal
6496 var clickFunction = function () {
6497
6498 //console.log("click function");
6499 var node = mesh.getNode(this.id);
6500 if (node.getState() == 0) {
6501 for (O in nodesByLoc)
6502 if (nodesByLoc[O].getNodeInViewportStatus()) {
6503 nodesByLoc[O].sub('').off("mouseup");
6504 }
6505 node.updateHtmlNodeState(1);
6506 //console.log($('.transparentNode').length);
6507 if ($('.transparentNode').length==0) {
6508 //console.log("put on top");
6509 putOnTop(node.getId());
6510 }
6511 else {
6512 // What if one node is transparent ?
6513 }
6514
6515 //var HT=node.getHtmlNode(); // Not used anywhere else ?!
6516 //if(me.getSelectedNodes().length<1)
6517 //if(me.getSelectedNodes().length<1 && !($(mesh.menu.getHtmlMenuSelector()).children("[class*=close]").length > 0 && !configBehaviour.moveOnMenuOption && !configBehaviour.alwaysShowInfo))
6518 //{
6519 //console.log("click, dont drag");
6520 //dragAndDrop(this);
6521 //}
6522 //else if ($('.closeTransparentButtonIcon').length > 0)
6523 //{
6524 //console.log("exception : transparency");
6526 //}
6527 } else {
6528 for (O in nodesByLoc)
6529 if (nodesByLoc[O].getNodeInViewportStatus()) {
6530 nodesByLoc[O].sub('').off("mouseup");
6531 }
6532 node.updateHtmlNodeState(0);
6533 putDown(node.getId());
6534 }
6535 };
6536
6537
6538 // Behaviour when a node is selected : red solid border
6539 var dblclickFunction = function() {
6540
6541 var node = mesh.getNode(this.id); // TO DO : how to be sure/consider each case (selected/node/iframe/id) ?
6542
6543 if(node.getSelectedStatus()==false)
6544 node.updateSelectedStatus(true);
6545 else
6546 node.updateSelectedStatus(false);
6547
6548 if(selectedNodes.length>2) { // More than two nodes : the first one is unselected
6549 selectedNodes[0].updateSelectedStatus(false);
6550 }
6551 else if (selectedNodes.length == 2) { // Two nodes : they switch position (switchLocation) or are placed besides (switch LocationShiftColumnLine)
6552 me.switchLocationShiftColumnLine(selectedNodes[0],selectedNodes[1],true,true)
6553 // me.switchLocation(selectedNodes[0],selectedNodes[1],true,true)
6554 selectedNodes[0].updateSelectedStatus(false);
6555 //selectedNodes[1].updateSelectedStatus(true);
6556
6557 }
6558 };
6559
6560
6561 var NodeEvent = {
6562
6563 mouseenter: mouseEnterFunction ,
6564
6565 mouseleave: mouseLeaveFunction,
6566
6567 click: clickFunction,
6568
6569 dblclick: dblclickFunction
6570
6571 };
6572
6573 $('.node').on(NodeEvent);
6574
6575 var clickOnOff = function(){
6576 if (emit_click("onoff",this.id))
6577 return
6578 var id = this.id.replace("onoff", "");
6579 var node = nodesById["node"+id];
6580 if( node.getOnOffStatus() ) {
6581 SetOff(id);
6582 } else {
6583 SetOn(id);
6584 }
6585 }
6586
6587 var OOFEvent = {
6588 click: clickOnOff
6589 };
6590
6591 $('.onoff').on(OOFEvent);
6592
6593 clickHB = function(){
6594 //console.log("Hitbox " + id + " clicked");
6595 if((me.getZoomSelection() == false) && (currentSelectedTag == "")) { // Default behaviour : not selecting nodes for a zoom, not in tag mode
6596 var HB = $('#'+this.id);
6597 //console.log(this.id, HB);
6598 var id = this.id.replace("hitbox", "");
6599 var HBcolor = HB.css('background-color');
6600 if(HBcolor == colorHBselectedRGB) { // Check if the node is already selected
6601 HB.css({backgroundColor : colorHBonfocus}); // Return to focused state only
6602 } else {
6603 HB.css({backgroundColor : colorHBselected}); // Select node
6604 }
6605 if(me.getNodesToToggle().length == 0) {
6606 addNodeToToggle(id);
6607 }
6608 else if(me.getNodesToToggle().length == 1) {
6609 var nodesToToggle = me.getNodesToToggle();
6610 if(id!=nodesToToggle[0]) {
6611 addNodeToToggle(id);
6612 var node1 = me.getNode(nodesToToggle[0]);
6613 var node2 = me.getNode(nodesToToggle[1]);
6614 me.switchLocationShiftColumnLine(node1,node2,true,true);
6615 $('#hitbox'+nodesToToggle[0]).css('background-color', colorHBdefault);
6616 $('#hitbox'+nodesToToggle[1]).css('background-color', colorHBdefault);
6617 nodesToToggle.splice(0,2);
6618 nodesToToggle.splice(0,2);
6619 } else {
6620 console.log("This node is already stored");
6621 }
6622 } else {
6623 console.log("Problem with nodesToToggle, its length shouldn’t exceed 2 !");
6624 }
6625 }
6626 else if (me.getZoomSelection() == true) {
6627 console.log("Select Zoom with hitbox.");
6628 clickHBSelect(id=this.id);
6629 }
6630 else if (currentSelectedTag !="") {
6631 console.log("Add Tag with hitbox.");
6632 clickHBTag(id=this.id);
6633 }
6634
6635
6636
6637 };
6638
6639 nodeSelect = function(node,HB) {
6640 if(node.getSelectedStatus()==false) {
6641 node.updateSelectedStatus(true);
6642 me.addNodeToZoom(node);
6643 HB.css({backgroundColor : colorHBtoZoom});
6644 } else {
6645 node.updateSelectedStatus(false);
6646 me.removeNodeToZoom(node);
6647 HB.css({backgroundColor : colorHBdefault});
6648 }
6649 }
6650
6651 clickHBSelect = function(id__){
6652 if (typeof this.id == 'undefined')
6653 var id_ = id__;
6654 else
6655 var id_ = this.id;
6656 //console.log("click HBZoom");
6657 var HB = $('#' + id_);
6658 try {
6659 var id = id_.replace("hitbox", "");
6660 //console.log(this.id, id, HB);
6661 var node = me.getNode(id);
6662 nodeSelect(node,HB)
6663 } catch(e) {
6664 console.log("Error in clickHBSelect.");
6665 }
6666 };
6667
6668 clickHBTag = function(id__){
6669 if (typeof this.id == 'undefined')
6670 var id_ = id__;
6671 else
6672 var id_ = this.id;
6673 //console.log("click HBTag", this);
6674 if (emit_click("hitbox",id_))
6675 return
6676 var HB = $('#' + id_);
6677 if(currentSelectedTag != "") {
6678 var id = id_.replace("hitbox", "");
6679 var node = me.getNode(id);
6680 node.getStickers().addSticker(currentSelectedTag, attributedTagsColorsArray[currentSelectedTag],true);
6681 addBorderBlink($("#iframe"+id),attributedTagsColorsArray[currentSelectedTag])
6682 node.addElementToNodeTagList(currentSelectedTag);
6683 $('.sticker').off();
6684 $('.sticker').on({
6685 click : clickSticker
6686 });
6687 $('#tag-notif').text("Added tag " + currentSelectedTag + " to tile " + id);
6688 } else {
6689 $('#tag-notif').text("No tag currently selected, you may need to click on a tag in the legend to select it, or to create a new one?");
6690 }
6691 };
6692
6693
6694 var HBEvent = {
6695
6696 //mouseenter: mouseEnterHB ,
6697 click: clickHB/*,
6698
6699dblclick: dblclickFunction*/
6700
6701 };
6702 $('.hitbox').on(HBEvent);
6703
6704 var mouseEnterHandle = function(e){
6705 if ($("#" + this.id).ontouchstart == undefined) {
6706 $("#" + this.id).off("mouseleave");
6707 $("#" + this.id).off("mouseup");
6708 //console.log("enter", this.id);
6709 if($('#' + this.id).hasClass("drag-handle-on")) {
6710 for (O in nodesByLoc)
6711 if (nodesByLoc[O].getNodeInViewportStatus()) {
6712 nodesByLoc[O].sub('').off("mouseenter");
6713 }
6714 $('#'+this.id).css('-webkit-transform','scale(2)').css('-moz-transform','scale(2)');
6715 var nodeToDrag = this.id.replace("handle", "");
6716 if(_allowDragAndDrop && $('.node').filter('.ui-draggable').length == 0) {
6717 // To adapt for multiple draggable tiles at the same time
6718 //console.log(nodeToDrag);
6719 $("#" + this.id).on("mousedown", function(e){
6720 dragAndDrop(nodeToDrag);
6721 })
6722 }
6723
6724 $("#" + this.id).on("mouseup", function(e){
6725 var nodeToDrop = this.id.replace("handle", "");
6726 me.dropNode(nodeToDrop);
6727 $('#'+this.id).css('-webkit-transform','scale(1)').css('-moz-transform','scale(1)');
6728 refreshNodes(nodeToDrop);
6729 me.globalLocationProvider();
6730 me.meshEventReStart();
6731
6732 $("#" + this.id).on("mouseleave", function(e){
6733 var nodeToDrop = this.id.replace("handle", "");
6734 refreshNodes(nodeToDrop);
6735 me.meshEventReStart();
6736 $('#'+nodeToDrag).on(NodeEvent);
6737 });
6738 $("#" + this.id).off("mousedown");
6739 $("#" + this.id).on("mousedown", function(e){
6740 $('#'+nodeToDrag).on(NodeEvent);
6741 $("#" + this.id).mouseenter();
6742 });
6743 $('#'+nodeToDrag).on(NodeEvent);
6744 }).on("mouseleave", function(e){
6745 $('#'+this.id).css('-webkit-transform','scale(1)').css('-moz-transform','scale(1)');
6746 });
6747 }
6748 if ($('.node').filter('.ui-draggable').length == 0)
6749 for (O in nodesByLoc)
6750 if (nodesByLoc[O].getNodeInViewportStatus()) {
6751 nodesByLoc[O].sub('').on("mousenter");
6752 }
6753 }
6754
6755 };
6756
6757 var handleEvent = {
6758 mouseenter: mouseEnterHandle,
6759 };
6760 if (!touchok) {
6761 console.log("No Touch.");
6762 };
6763 $('.handle').on(handleEvent);
6764
6765 var mouseEnterRotate = function(e){
6766 if ($("#" + this.id).ontouchstart == undefined) {
6767 var RotateBut=$("#" + this.id);
6768 RotateBut.off("mousedown");
6769 RotateBut.off("mouseup");
6770 RotateBut.off("mousemove");
6771 RotateBut.off("mouseleave");
6772 RotateBut.off("mouseenter");
6773 RotateBut.off("dblclick");
6774
6775 var id = this.id.replace("rotate", "");
6776
6777 var node = mesh.getNode(id);
6778 var nodeToRotate=$('#' + id);
6779
6780 var rotstate_angle = 0.;
6781 var rotate_ok=false
6782
6783 RotateBut.on("mousedown", function(e){
6784 rotate_ok=true
6785 RotateBut.css('-webkit-transform','scale(2)').css('-moz-transform','scale(2)');
6786 });
6787
6788 RotateBut.on("mousemove", function(e){
6789 if (rotate_ok) {
6790
6791 rotstate_angle = node.getNodeAngle();
6792 if (!! configBehaviour.smoothRotation) {
6793 if ( rotstate_angle > 340 || rotstate_angle < 20)
6794 rotstate_angle=0;
6795 else if ( rotstate_angle > 70 && rotstate_angle < 110)
6796 rotstate_angle=90;
6797 else if ( rotstate_angle > 160 && rotstate_angle < 200)
6798 rotstate_angle=180;
6799 else if ( rotstate_angle > 250 && rotstate_angle < 290)
6800 rotstate_angle=270;
6801 } else {
6802 rotstate_angle = rotstate_angle+RotInc;
6803 if (rotstate_angle > 360)
6804 rotstate_angle=RotInc;
6805 }
6806 node.setNodeAngle(rotstate_angle);
6807
6808 nodeToRotate.css({ '-webkit-transform': 'rotate('+rotstate_angle+'deg)',
6809 '-moz-transform': 'rotate('+rotstate_angle+'deg)',
6810 '-o-transform': 'rotate('+rotstate_angle+'deg)',
6811 '-ms-transform': 'rotate('+rotstate_angle+'deg)',
6812 'transform': 'rotate('+rotstate_angle+'deg)'
6813 });
6814 e.stopPropagation();
6815 };
6816 }).on("mouseup", function(e){
6817 if (rotate_ok) {
6818 rotate_ok=false
6819
6820 RotateBut.off("mousemove");
6821 RotateBut.off("mouseleave");
6822 RotateBut.off("mouseup");
6823
6824 RotateBut.on("mouseleave", function(e){
6825
6826 RotateBut.css('-webkit-transform','scale(0.5)').css('-moz-transform','scale(0.5)');
6827 e.stopPropagation();
6828 });
6829 e.stopPropagation();
6830 RotateBut.on("mouseenter",mouseEnterRotate)
6831 };
6832 }).on("dblclick", function(e){
6833 node.setNodeAngle(0);
6834
6835 nodeToRotate.css({ '-webkit-transform': 'rotate('+0+'deg)',
6836 '-moz-transform': 'rotate('+0+'deg)',
6837 '-o-transform': 'rotate('+0+'deg)',
6838 '-ms-transform': 'rotate('+0+'deg)',
6839 'transform': 'rotate('+0+'deg)'
6840 });
6841 e.stopPropagation();
6842 });
6843 };
6844 };
6845
6846 var rotateEvent = {
6847 mouseenter: mouseEnterRotate,
6848 };
6849 $('.rotate').on(rotateEvent);
6850
6851 // multi-touch support
6852 if (touchok) {
6853 var dragging = new Map(); // maps touch IDs to drag state objects
6854 var rotating = new Map();
6855
6856 // $(".handle").addClass("drag-handle-on");
6857 //$(".handle").addClass("drag-handle-dragging");//.removeClass("drag-handle-on");
6858
6859 $('.node').on("mouseleave");
6860 $('.node').on("mouseup");
6861
6862 var touchstartHandle = function (ev) {
6863 // alert("touchstart");
6864 //alert("ev.changedTouches.length"+ev.changedTouches.length);
6865 var hastouched=false;
6866
6867 for (var i = 0; i < ev.changedTouches.length; i++) {
6868 var touch = ev.changedTouches[i];
6869 var targetid=touch.target.id;
6870 if (targetid.indexOf('handle') >= 0 && _allowDragAndDrop ) {
6871 $('.handle').off();
6872 var id = targetid.replace("handle", "");
6873 //var node = mesh.getNode(id);
6874 var nodeToDrag=$('#' + id);
6875 var thishandle=$('#'+touch.target.id);
6876 thishandle.addClass("drag-handle-dragging");
6877
6878 for (O in nodesByLoc)
6879 if (nodesByLoc[O].getNodeInViewportStatus()) {
6880 nodesByLoc[O].sub('').off("mouseenter");
6881 }
6882 nodeToDrag.off("mouseleave");
6883
6884 var rect = {
6885 top: parseInt(nodeToDrag[0].style.top.replace('px','')),
6886 left: parseInt(nodeToDrag[0].style.left.replace('px','')),
6887 };
6888 //console.log("touchstart i "+i+" targetid "+targetid+" rect "+rect.top +" "+rect.left );
6889 dragging.set(touch.identifier, {
6890 target: touch.target,
6891 top: rect.top,
6892 left: rect.left,
6893 prevX: touch.pageX,
6894 prevY: touch.pageY,
6895 });
6896 // for (var [key, value] of dragging) {
6897 // console.log("dragging : "+key + " = {" + value.left+", "+value.top+", "+value.prevX+", "+value.prevY+"}");
6898 // }
6899
6900 //nodeToDrag[0].style.background='red';
6901 hastouched=true;
6902 // } else {
6903 // console.log("touchstart err i "+i+" targetid "+targetid);
6904 $('#'+targetid).css('-webkit-transform','scale(2)').css('-moz-transform','scale(2)');
6905 } else if (targetid.indexOf('rotate') >= 0) {
6906 var id = targetid.replace("rotate", "");
6907 var nodeToDrag=$('#' + id);
6908 var node = mesh.getNode(id);
6909 var centerX = nodeToDrag[0].style.left.replace('px','')+(nodeToDrag[0].style.width.replace('px','')/2);
6910 var centerY = nodeToDrag[0].style.top.replace('px','')+(nodeToDrag[0].style.height.replace('px','')/2);
6911 rotating.set(touch.identifier, {
6912 target: touch.target,
6913 angle: node.getNodeAngle(),
6914 centerX: centerX,
6915 centerY: centerY,
6916 });
6917 //console.log("centerX : "+rotating.get(touch.identifier).centerX+" centerY : "+rotating.get(touch.identifier).centerY);
6918 console.log("centerX : "+centerX+" centerY : "+centerY);
6919 $('#'+targetid).css('-webkit-transform','scale(2)').css('-moz-transform','scale(2)');
6920 }
6921 }
6922 if (hastouched) {
6923 hastouched=false;
6924 // ev.preventDefault();
6925 }
6926 };
6927
6928 var touchmoveHandle = function (ev) {
6929 for (var i = 0; i < ev.changedTouches.length; i++) {
6930 // for each moved touch, see if we have a corresponding dragstate
6931 var touch = ev.changedTouches[i];
6932 var targetid=touch.target.id;
6933 var dragstate = dragging.get(touch.identifier);
6934 var rotstate = rotating.get(touch.identifier);
6935 // for (var [key, value] of dragging) {
6936 // console.log(key + " = {" + value.left+", "+value.top+", "+value.prevX+", "+value.prevY+"}");
6937 // }
6938 if (targetid.indexOf('handle') >= 0 && _allowDragAndDrop && dragstate) {
6939 var id = targetid.replace("handle", "");
6940 var node = mesh.getNode(id);
6941 var nodeToDrag=$('#' + id);
6942 var thishandle=$('#'+touch.target.id);
6943 dragstate.left = parseInt(dragstate.left)+touchspeed*(touch.pageX - dragstate.prevX);
6944 dragstate.top = parseInt(dragstate.top)+touchspeed*(touch.pageY - dragstate.prevY);
6945 nodeToDrag.css({left: dragstate.left+'px',
6946 top: dragstate.top+'px'});
6947 //nodeToDrag[0].style.background='green';
6948
6949 // if (touch.screenX == dragstate.prevX && touch.screenY == dragstate.prevY) {
6950 // thishandle.off("touchmove");
6951 // thishandle.on("touchend");
6952 // } else {
6953 // //update cursor position
6954 dragstate.prevX = touch.pageX;
6955 dragstate.prevY = touch.pageY;
6956 // }
6957 // console.log("touchmoveFunction screenX "+ dragstate.prevX +" left "+dragstate.left+
6958 // " screenY " + dragstate.prevY + " top "+dragstate.top );
6959 // dragstate.prevX = dragstate.left;
6960 // dragstate.prevY = dragstate.top;
6961 ev.stopPropagation();
6962 }
6963 else if (targetid.indexOf('rotate') >= 0 && rotstate && configBehaviour.smoothRotation) {
6964 var id = targetid.replace("rotate", "");
6965 var node = mesh.getNode(id);
6966 var nodeToDrag=$('#' + id);
6967 var thishandle=$('#'+touch.target.id);
6968
6969 rotstate.angle = rotstate.angle+RotInc;
6970 if (rotstate.angle > 360)
6971 rotstate.angle=RotInc;
6972
6973 console.log(id+" move rotstate.angle : "+rotstate.angle);
6974 node.setNodeAngle(rotstate.angle);
6975
6976 nodeToDrag.css({ '-webkit-transform': 'rotate('+rotstate.angle+'deg)',
6977 '-moz-transform': 'rotate('+rotstate.angle+'deg)',
6978 '-o-transform': 'rotate('+rotstate.angle+'deg)',
6979 '-ms-transform': 'rotate('+rotstate.angle+'deg)',
6980 'transform': 'rotate('+rotstate.angle+'deg)'
6981 });
6982 //transform-origin: 50% 50%, (ou center center)
6983 }
6984 }
6985 //ev.preventDefault()
6986 }
6987
6988
6989
6990 var touchendHandle = function (ev) {
6991 //console.log("touchend");
6992 var hastouched=false;
6993 // for each touch that ended, reset the dragstate
6994 for (var i = 0; i < ev.changedTouches.length; i++) {
6995 var touch = ev.changedTouches[i];
6996 var dragstate = dragging.get(touch.identifier);
6997 var rotstate = rotating.get(touch.identifier);
6998 var targetid=touch.target.id;
6999 if (targetid.indexOf('handle') >= 0 && _allowDragAndDrop && dragstate) {
7000 var thishandle=$('#'+touch.target.id);
7001 var id = targetid.replace("handle", "");
7002 var nodeToDrag=$('#' + id);
7003 //console.log("touchend i "+i+" targetid "+targetid+" length "+ev.changedTouches.length);
7004
7005 //nodeToDrag[0].style.background='blue';
7006 // nodeToDrag.removeClass("ui-draggable-dragging");
7007
7008 me.dropNode(id);
7009 me.globalLocationProvider();
7010
7011 // for (var [key, value] of dragging) {
7012 // console.log("dragging : "+key + " = {" + value.left+", "+value.top+", "+value.prevX+", "+value.prevY+"}");
7013 // }
7014 dragging.delete(touch.identifier);
7015 // $(thishandle).removeClass("drag-handle-on");
7016 $(thishandle).removeClass("drag-handle-dragging");
7017
7018 hastouched=true;
7019
7020 nodeToDrag.on("mouseleave");
7021 if (dragging.size == 0)
7022 for (O in nodesByLoc)
7023 if (nodesByLoc[O].getNodeInViewportStatus()) {
7024 nodesByLoc[O].sub('').on("mouseenter");
7025 }
7026
7027 $('#'+targetid).css('-webkit-transform','scale(1)').css('-moz-transform','scale(1)');
7028 } else if (targetid.indexOf('rotate') >= 0 && rotstate) {
7029 var id = targetid.replace("rotate", "");
7030 var node = mesh.getNode(id);
7031 var nodeToDrag=$('#' + id);
7032
7033 if (!! configBehaviour.smoothRotation) {
7034 if ( rotstate.angle > 340 || rotstate.angle < 20)
7035 rotstate.angle=0;
7036 else if ( rotstate.angle > 70 && rotstate.angle < 110)
7037 rotstate.angle=90;
7038 else if ( rotstate.angle > 160 && rotstate.angle < 200)
7039 rotstate.angle=180;
7040 else if ( rotstate.angle > 250 && rotstate.angle < 290)
7041 rotstate.angle=270;
7042 } else {
7043 rotstate.angle = rotstate.angle+RotInc;
7044 if (rotstate.angle > 360)
7045 rotstate.angle=RotInc;
7046 }
7047
7048 console.log(id+" end rotstate.angle : "+rotstate.angle);
7049 node.setNodeAngle(rotstate.angle);
7050
7051 nodeToDrag.css({ '-webkit-transform': 'rotate('+rotstate.angle+'deg)',
7052 '-moz-transform': 'rotate('+rotstate.angle+'deg)',
7053 '-o-transform': 'rotate('+rotstate.angle+'deg)',
7054 '-ms-transform': 'rotate('+rotstate.angle+'deg)',
7055 'transform': 'rotate('+rotstate.angle+'deg)'
7056 });
7057
7058 // var tx=rotstate.centerX - (nodeToDrag[0].style.left.replace('px','')+(nodeToDrag[0].style.width.replace('px','')/2));
7059 // var ty=rotstate.centerY - (nodeToDrag[0].style.top.replace('px','')+(nodeToDrag[0].style.height.replace('px','')/2));
7060 // nodeToDrag.css({ '-webkit-transform': 'translate('+tx+'px,'+ty+'px)',
7061 // '-moz-transform': 'translate('+tx+'px,'+ty+'px)',
7062 // '-o-transform': 'translate('+tx+'px,'+ty+'px)',
7063 // '-ms-transform': 'translate('+tx+'px,'+ty+'px)',
7064 // 'transform': 'translate('+tx+'px,'+ty+'px)'
7065 // });
7066
7067 rotating.delete(touch.identifier);
7068 $('#'+targetid).css('-webkit-transform','scale(1)').css('-moz-transform','scale(1)');
7069 }
7070 }
7071 if (hastouched) {
7072 me.meshEventReStart();
7073 //ev.stopPropagation();
7074 //ev.preventDefault();
7075 hastouched=false;
7076 }
7077 };
7078
7079 var touchhandleEvent = {
7080 touchstart: touchstartHandle,
7081 touchmove: touchmoveHandle,
7082 touchend: touchendHandle,
7083 }
7084
7085 htmlPrimaryParent.on(touchhandleEvent);
7086 }
7087
7088 // zoomNodecodes : on click, Zoom
7089 this.clickzoomNode = function(){
7090
7091 if ( configBehaviour.sharedZoomNodes && emit_click("zoomNodeButtonIcon",this.id))
7092 return
7093
7094 //console.log("zoomNode clicked", this.id);
7095 var id = this.id.replace("zoomNode", "");
7096
7097 var node = me.getNode(id);
7098
7099 // Variables for magnifyingGlass
7100 var nodeZoomTab = new Array();
7101 nodeZoomTab.push(node);
7102 var ratio =spread.Y/spread.X;
7103 var initSpread = spread;
7104
7105 for (O in nodesByLoc)
7106 if (nodesByLoc[O].getNodeInViewportStatus()) {
7107 nodesByLoc[O].sub('').off();
7108 nodesByLoc[O].sub('hitbox').off("click").on("click", clickHBSelect);
7109 nodesByLoc[O].sub('hitbox').off("mouseenter");
7110 }
7111 _allowDragAndDrop = false;
7112
7113 me.magnifyingGlass(nodeZoomTab,ratio,initSpread);
7114 if ( configBehaviour.sharedZoomNodes )
7115 $('#buttonUnzoom').on('click',function(){ emit_click("unzoomButtonIcon","buttonUnzoom") } )
7116 };
7117
7118 this.init_click_zoomNode = function() {
7119 $('.zoomNodeButtonIcon').on({
7120 click : me.clickzoomNode
7121 });
7122 }
7123
7124 // QRcodes : on click, Zoom
7125 clickQRcode = function(){
7126 //console.log("QRcode clicked", this.id);
7127 if (emit_click("qrcode",this.id))
7128 return
7129 var splittedId = this.id.split("qrcode");
7130 var nodeId = splittedId.pop();
7131 var divnode = $('#'+nodeId);
7132 var node = nodesById["node"+nodeId];
7133 var theqrcode = node.getQRcode();
7134 var thisqrcode = $('#qrcode'+nodeId);
7135 var qrcodeZoom=theqrcode.getZoom();
7136
7137 if (qrcodeZoom) {
7138 thisqrcode.css({
7139 position : "absolute",
7140 top : parseInt(divnode.css("height"))-50,
7141 left : parseInt(divnode.css("width"))-50,
7142 width : 130,
7143 height : 130,
7144 zIndex : 111,
7145 });
7146 thisqrcode.css('-webkit-transform','scale('+1.+')').css('-moz-transform','scale('+1.+')');
7147 $('#qqrcode'+nodeId).css({
7148 zIndex : 199,
7149 });
7150 theqrcode.setZoom(false);
7151 } else {
7152 thisqrcode.css('-webkit-transform','scale('+400./130+')').css('-moz-transform','scale('+400./130+')');
7153 thisqrcode.css({
7154 position : "absolute",
7155 top : parseInt(divnode.css("height"))-200,
7156 left : parseInt(divnode.css("width"))-200,
7157 zIndex : 999,
7158 });
7159 $('#qqrcode'+nodeId).css({
7160 zIndex : 999,
7161 });
7162 theqrcode.setZoom(true);
7163 }
7164 $('#iqrcode'+nodeId).css({
7165 width : thisqrcode.css("width"),
7166 height : thisqrcode.css("height"),
7167 });
7168 $('#qqrcode'+nodeId).css({
7169 top : -parseInt(thisqrcode.css("height"))*1.1,
7170 width : parseInt(thisqrcode.css("width")),
7171 height : parseInt(thisqrcode.css("height")),
7172 });
7173 };
7174
7175 //when the window is reloaded...
7176 $( window ).resize( function() {
7177
7178 if(ColumnStyle=="static") {
7179 mesh.changeNodeSize();
7180 }
7181 else if(ColumnStyle=="dynamic" && numOfColumns==maxNumOfColumns) {
7182 me.computeNumColumns();
7183 mesh.globalLocationProvider();
7184 mesh.changeNodeSize();
7185 } else {
7186 me.computeNumColumns();
7187 mesh.globalLocationProvider();
7188 }
7189
7190 })
7191
7192 }; // End meshEventStart
7193
7194};
7195 })