From b6747c29d1d216b50dac1e9a818b4e9226b60b5a Mon Sep 17 00:00:00 2001 From: kinimesi Date: Tue, 19 Dec 2017 16:34:39 +0300 Subject: [PATCH 01/97] Updated version number to 1.0.5 --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index ec4a40700..e6c8ed340 100644 --- a/index.html +++ b/index.html @@ -656,7 +656,7 @@

About

"; - - $('#template-reaction-dissociated-table :input.template-reaction-textbox').last().closest('tr').after(html); + + ""; + $('#template-reaction-dissociated-table :input.template-reaction-textbox').last().closest('tr').after(html); + } + else if( type == "left"){ + html += "class='template-reversible-input-delete-button' width='16px' height='16px' name='" + i + "' src='app/img/toolbar/delete-simple.svg'/>"; + $('#template-reversible-input-table :input.template-reaction-textbox').last().closest('tr').after(html); + } + else{ + html += "class='template-reversible-output-delete-button' width='16px' height='16px' name='" + i + "' src='app/img/toolbar/delete-simple.svg'/>"; + $('#template-reversible-output-table :input.template-reaction-textbox').last().closest('tr').after(html); + } return html; }, - removeMacromolecule: function (i) { - $('#template-reaction-dissociated-table :input.template-reaction-textbox[name="'+i+'"]').closest('tr').remove(); + removeMacromolecule: function (type, i) { + if(type == "reaction"){ + $('#template-reaction-dissociated-table :input.template-reaction-textbox[name="'+i+'"]').closest('tr').remove();; + } + else if(type == "left"){ + $('#template-reversible-input-table :input.template-reaction-textbox[name="'+i+'"]').closest('tr').remove(); + } + else{ + $('#template-reversible-output-table :input.template-reaction-textbox[name="'+i+'"]').closest('tr').remove(); + } }, - switchInputOutput: function () { - var saveHtmlContent = $("#reaction-template-left-td").html(); - $("#reaction-template-left-td").html($("#reaction-template-right-td").html()); - $("#reaction-template-right-td").html(saveHtmlContent); + switchInputOutput: function (e) { + var self = this; + if(e == "association") { + $('#reaction-template-left-td').html(self.associatedHTMLContent); + $('#reaction-template-right-td').html(self.dissociatedHTMLContent); + } + else if(e == "dissociation"){ + $('#reaction-template-left-td').html(self.dissociatedHTMLContent); + $('#reaction-template-right-td').html(self.associatedHTMLContent); + } + else{ + $('#reaction-template-left-td').html(self.reversibleInputHTMLContent); + $('#reaction-template-right-td').html(self.reversibleOutputHTMLContent); + self.disableDeleteButtonStyle("left"); + self.disableDeleteButtonStyle("right"); + } }, getAllParameters: function () { var templateType = $('#reaction-template-type-select').val(); @@ -1734,6 +1764,12 @@ var ReactionTemplateView = Backbone.View.extend({ var macromoleculeList = $('#template-reaction-dissociated-table :input.template-reaction-textbox').map(function(){ return $(this).val() }).toArray(); + var reversibleInputMacromoleculeList = $('#template-reversible-input-table :input.template-reaction-textbox').map(function(){ + return $(this).val(); + }).toArray(); + var reversibleOutputMacromoleculeList = $('#template-reversible-output-table :input.template-reaction-textbox').map(function(){ + return $(this).val(); + }).toArray(); // enable complex name only if the user provided something var templateReactionEnableComplexName = $.trim(templateReactionComplexName).length != 0; @@ -1741,16 +1777,39 @@ var ReactionTemplateView = Backbone.View.extend({ templateType: templateType, templateReactionComplexName: templateReactionComplexName, macromoleculeList: macromoleculeList, + reversibleInputMacromoleculeList: reversibleInputMacromoleculeList, + reversibleOutputMacromoleculeList: reversibleOutputMacromoleculeList, templateReactionEnableComplexName: templateReactionEnableComplexName } }, - disableDeleteButtonStyle: function () { - $("img.template-reaction-delete-button").css("opacity", 0.2); - $("img.template-reaction-delete-button").css("cursor", "default"); + disableDeleteButtonStyle: function (type) { + if(type == "reaction"){ + $("img.template-reaction-delete-button").css("opacity", 0.2); + $("img.template-reaction-delete-button").css("cursor", "default"); + } + else if(type == "left"){ + $("img.template-reversible-input-delete-button").css("opacity", 0.2); + $("img.template-reversible-input-delete-button").css("cursor", "default"); + } + else{ + $("img.template-reversible-output-delete-button").css("opacity", 0.2); + $("img.template-reversible-output-delete-button").css("cursor", "default"); + } }, - enableDeleteButtonStyle: function() { - $("img.template-reaction-delete-button").css("opacity",1); - $("img.template-reaction-delete-button").css("cursor", "pointer"); + enableDeleteButtonStyle: function(type) { + if(type == "reaction"){ + $("img.template-reaction-delete-button").css("opacity",1); + $("img.template-reaction-delete-button").css("cursor", "pointer"); + } + else if(type == "left"){ + $("img.template-reversible-input-delete-button").css("opacity",1); + $("img.template-reversible-input-delete-button").css("cursor", "pointer"); + } + else{ + $("img.template-reversible-output-delete-button").css("opacity",1); + $("img.template-reversible-output-delete-button").css("cursor", "pointer"); + } + }, initialize: function() { @@ -1759,7 +1818,8 @@ var ReactionTemplateView = Backbone.View.extend({ $(document).on('change', '#reaction-template-type-select', function (e) { var valueSelected = $(this).val(); - self.switchInputOutput(); + self.switchInputOutput(valueSelected); + self.disableDeleteButtonStyle("reaction"); }); $(document).on("change", "#template-reaction-complex-name", function(e){ @@ -1770,8 +1830,8 @@ var ReactionTemplateView = Backbone.View.extend({ $(document).on("click", "#template-reaction-add-button", function (event) { // get the last input name and add 1 var nextIndex = parseInt($('#template-reaction-dissociated-table :input.template-reaction-textbox').last().attr('name')) + 1; - self.addMacromolecule(nextIndex); - self.enableDeleteButtonStyle(); + self.addMacromolecule("reaction",nextIndex); + self.enableDeleteButtonStyle("reaction"); }); $(document).on('change', ".template-reaction-textbox", function () { @@ -1784,9 +1844,43 @@ var ReactionTemplateView = Backbone.View.extend({ return; } var index = parseInt($(this).attr('name')); - self.removeMacromolecule(index); + self.removeMacromolecule("reaction",index); if($('#template-reaction-dissociated-table :input.template-reaction-textbox').length <= 2){ - self.disableDeleteButtonStyle(); + self.disableDeleteButtonStyle("reaction"); + } + }); + + $(document).on("click", "#template-reversible-input-add-button", function(event){ + var nextIndex = parseInt($('#template-reversible-input-table :input.template-reaction-textbox').last().attr('name')) + 1; + self.addMacromolecule( "left", nextIndex); + self.enableDeleteButtonStyle("left"); + }); + + $(document).on("click", "#template-reversible-output-add-button", function(event){ + var nextIndex = parseInt($('#template-reversible-output-table :input.template-reaction-textbox').last().attr('name')) + 1; + self.addMacromolecule( "right", nextIndex); + self.enableDeleteButtonStyle("right"); + }); + + $(document).on("click", ".template-reversible-input-delete-button", function(event){ + if($('#template-reversible-input-table :input.template-reaction-textbox').length <= 1){ + return; + } + var index = parseInt($(this).attr('name')); + self.removeMacromolecule("left",index); + if($('#template-reversible-input-table :input.template-reaction-textbox').length <= 1){ + self.disableDeleteButtonStyle("left"); + } + }); + + $(document).on("click", ".template-reversible-output-delete-button", function(event){ + if($('#template-reversible-output-table :input.template-reaction-textbox').length <= 1){ + return; + } + var index = parseInt($(this).attr('name')); + self.removeMacromolecule("right",index); + if($('#template-reversible-output-table :input.template-reaction-textbox').length <= 1){ + self.disableDeleteButtonStyle("right"); } }); @@ -1808,7 +1902,10 @@ var ReactionTemplateView = Backbone.View.extend({ var complexName = params.templateReactionEnableComplexName ? params.templateReactionComplexName : undefined; var tilingPaddingVertical = chiseInstance.calculatePaddings(currentLayoutProperties.tilingPaddingVertical); var tilingPaddingHorizontal = chiseInstance.calculatePaddings(currentLayoutProperties.tilingPaddingHorizontal); - + if(templateType == "reversible"){ + macromoleculeList = params.reversibleInputMacromoleculeList; + complexName = params.reversibleOutputMacromoleculeList; + } chiseInstance.createTemplateReaction(templateType, macromoleculeList, complexName, undefined, tilingPaddingVertical, tilingPaddingHorizontal); $(self.el).modal('toggle'); @@ -1825,7 +1922,10 @@ var ReactionTemplateView = Backbone.View.extend({ self.disableDeleteButtonStyle(); $(self.el).modal('show'); - + self.associatedHTMLContent = $('#reaction-template-left-td').html(); + self.dissociatedHTMLContent = $('#reaction-template-right-td').html(); + self.reversibleInputHTMLContent = $('#reversible-template-left-td').html(); + self.reversibleOutputHTMLContent = $('#reversible-template-right-td').html(); return this; } }); @@ -1975,7 +2075,7 @@ var FontPropertiesView = Backbone.View.extend({ this.currentFontProperties = _.clone(this.defaultFontProperties); }, fontFamilies: ["", "Helvetica", "Arial", "Calibri", "Cambria", "Comic Sans MS", "Consolas", "Corsiva" - ,"Courier New" ,"Droid Sans", "Droid Serif", "Georgia", "Impact" + ,"Courier New" ,"Droid Sans", "Droid Serif", "Georgia", "Impact" ,"Lato", "Roboto", "Source Sans Pro", "Syncopate", "Times New Roman" ,"Trebuchet MS", "Ubuntu", "Verdana"], getOptionIdByFontFamily: function(fontfamily) { @@ -1991,35 +2091,35 @@ var FontPropertiesView = Backbone.View.extend({ if(self == null){ self = this; } - + var fontFamilies = self.fontFamilies; - + var html = ""; html += " checked<%}%>> - + @@ -1729,6 +1730,36 @@
-

Newt Editor version 1.0.4

+

Newt Editor version 1.0.5

From f53f5480d2739c16b273ac2935946a35eb27b3b6 Mon Sep 17 00:00:00 2001 From: kinimesi Date: Thu, 21 Dec 2017 15:06:29 +0300 Subject: [PATCH 02/97] Fixing #219 --- app/js/app-utilities.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/js/app-utilities.js b/app/js/app-utilities.js index 845f64887..781239aab 100644 --- a/app/js/app-utilities.js +++ b/app/js/app-utilities.js @@ -240,6 +240,10 @@ appUtilities.updateNetworkTabDesc = function (networkKey) { // get the map name from scratch pad of cy to use as the new tab description var mapName = this.getScratch(cy).currentGeneralProperties.mapName; + // if mapName is empty set it to "Pathway" #219 + if (!mapName) + mapName = "Pathway"; + // update the content of 'a' element that is contained by the related tab $('#' + tabId + ' a').text(mapName); }; From a73c8e0a939733f933b873af926dd6fe5f597862 Mon Sep 17 00:00:00 2001 From: kinimesi Date: Mon, 25 Dec 2017 15:54:15 +0300 Subject: [PATCH 03/97] Hotfix #220 --- app/js/app-utilities.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/js/app-utilities.js b/app/js/app-utilities.js index 781239aab..978051f9c 100644 --- a/app/js/app-utilities.js +++ b/app/js/app-utilities.js @@ -1943,6 +1943,10 @@ appUtilities.launchWithModelFile = function() { loadFromURI(uri_path, chiseInstance, promptInvalidURIWarning); function loadFromURL(filepath, chiseInstance, promptInvalidURLWarning){ + // get current general properties + var cyInstance = chiseInstance.getCy(); + var currentGeneralProperties = appUtilities.getScratch(cyInstance, 'currentGeneralProperties'); + var currentInferNestingOnLoad = currentGeneralProperties.inferNestingOnLoad; var loadCallbackSBGNMLValidity = function (text) { $.ajax({ @@ -1993,12 +1997,18 @@ appUtilities.launchWithModelFile = function() { lastModified: Date.now() }); + currentGeneralProperties.inferNestingOnLoad = true; chiseInstance.loadSBGNMLFile(fileToLoad, loadCallbackSBGNMLValidity, loadCallbackInvalidityWarning); }, error: function(xhr, ajaxOptions, thrownError){ loadCallbackInvalidityWarning(); } }); + + $(document).one("sbgnvizLoadFileEnd", function(){ + currentGeneralProperties.inferNestingOnLoad = currentInferNestingOnLoad; + appUtilities.mapTabGeneralPanel.render(); + }); } From d2ee70c40b70a80e5e33457ac666c0c8a4011f76 Mon Sep 17 00:00:00 2001 From: metincansiper Date: Tue, 9 Jan 2018 11:00:13 -0800 Subject: [PATCH 04/97] Trigger an event after dynamic resize operation is performed --- app/js/app-utilities.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/js/app-utilities.js b/app/js/app-utilities.js index 978051f9c..fbfec50e8 100644 --- a/app/js/app-utilities.js +++ b/app/js/app-utilities.js @@ -798,6 +798,9 @@ appUtilities.dynamicResize = function () { $("#network-panels-container, .network-panel").height(windowHeight * 0.85); $("#sbgn-inspector").height(windowHeight * 0.85); } + + // trigger an event to notify that newt components are dynamically resized + $(document).trigger('newtAfterDynamicResize'); }; /* appUtilities.nodeQtipFunction = function (node) { From f6ad15b5f65df620bc82f67a176f35fcc16134b0 Mon Sep 17 00:00:00 2001 From: metincansiper Date: Tue, 9 Jan 2018 15:40:51 -0800 Subject: [PATCH 05/97] Let network panels fill their parent instead of manually resizing them on dynamic resize --- app/css/chise.css | 4 ++-- app/js/app-utilities.js | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/app/css/chise.css b/app/css/chise.css index 6162555e2..2b2d500e4 100644 --- a/app/css/chise.css +++ b/app/css/chise.css @@ -185,8 +185,8 @@ body { } .network-panel { - height: 680px; - width: 800px; + height: 100%; + width: 100%; } #network-tabs-list-container { diff --git a/app/js/app-utilities.js b/app/js/app-utilities.js index 978051f9c..7c56891d7 100644 --- a/app/js/app-utilities.js +++ b/app/js/app-utilities.js @@ -427,9 +427,6 @@ appUtilities.createNewNetwork = function () { // physically open the new tab appUtilities.chooseNetworkTab(appUtilities.nextNetworkId); - // resize html components according to the window size - appUtilities.dynamicResize(); - // activate palette tab if (!$('#inspector-palette-tab').hasClass('active')) { $('#inspector-palette-tab a').tab('show'); @@ -783,7 +780,7 @@ appUtilities.dynamicResize = function () { //This is the margin on left and right of the main content when the page is //displayed var mainContentMargin = 10; - $("#network-panels-container, .network-panel").width(windowWidth * 0.8 - mainContentMargin); + $("#network-panels-container").width(windowWidth * 0.8 - mainContentMargin); $("#sbgn-inspector").width(windowWidth * 0.2 - mainContentMargin); var w = $("#sbgn-inspector-and-canvas").width(); $(".nav-menu").width(w); @@ -795,7 +792,7 @@ appUtilities.dynamicResize = function () { if (windowHeight > canvasHeight) { - $("#network-panels-container, .network-panel").height(windowHeight * 0.85); + $("#network-panels-container").height(windowHeight * 0.85); $("#sbgn-inspector").height(windowHeight * 0.85); } }; From 495f6f9f8133176b5162636399ffc37fea1e96b6 Mon Sep 17 00:00:00 2001 From: metincansiper Date: Tue, 9 Jan 2018 16:01:38 -0800 Subject: [PATCH 06/97] Call dynamic resize for one time in app-menu since it is no more called when a new tab is created --- app/js/app-menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/js/app-menu.js b/app/js/app-menu.js index 114f4d705..3deb7d79b 100644 --- a/app/js/app-menu.js +++ b/app/js/app-menu.js @@ -47,7 +47,7 @@ module.exports = function() { $(window).on('resize', _.debounce(dynamicResize, 100)); - // appUtilities.dynamicResize(); + dynamicResize(); layoutPropertiesView = appUtilities.layoutPropertiesView = new BackboneViews.LayoutPropertiesView({el: '#layout-properties-table'}); colorSchemeInspectorView = appUtilities.colorSchemeInspectorView = new BackboneViews.ColorSchemeInspectorView({el: '#color-scheme-template-container'}); From 90de5cc640d354a72e8309377f73430580cee1e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87and=C4=B1ro=C4=9Flu?= Date: Fri, 2 Feb 2018 16:25:41 +0300 Subject: [PATCH 07/97] Animate to the end of an edge (#224) Fixes #224 --- app/js/app-cy.js | 9 +++++ app/js/app-utilities.js | 78 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/app/js/app-cy.js b/app/js/app-cy.js index 5e37e14c4..f56de1329 100644 --- a/app/js/app-cy.js +++ b/app/js/app-cy.js @@ -199,6 +199,15 @@ module.exports = function (chiseInstance) { $("#highlight-processes-of-selected").trigger('click'); } }, + { + id: 'ctx-menu-animate-edge', + content: 'Navigate to Other End', + selector: 'edge', + onClickFunction: function (event) { + var cyTarget = event.target || event.cyTarget; + appUtilities.navigateToOtherEnd(cyTarget, event.renderedPosition, event.position); + } + }, ]); cy.clipboard({ diff --git a/app/js/app-utilities.js b/app/js/app-utilities.js index 0c0a00d2c..034179c7c 100644 --- a/app/js/app-utilities.js +++ b/app/js/app-utilities.js @@ -2058,4 +2058,82 @@ appUtilities.launchWithModelFile = function() { } } +appUtilities.navigateToOtherEnd = function(edge, mouse_rend, mouse_normal) { + + if(!edge.isEdge()){ + return; + } + + var cy = appUtilities.getActiveCy(); + var edge_pts = edge._private.rscratch.allpts; + + var source_node = edge.source(); + var target_node = edge.target(); + + var source_position = {x: edge_pts[0], y: edge_pts[1]}; + var target_position = {x: edge_pts[edge_pts.length-2], y: edge_pts[edge_pts.length-1]}; + + var source_loc = Math.pow((mouse_normal.x - source_position.x), 2) + Math.pow((mouse_normal.y - source_position.y), 2); + var target_loc = Math.pow((mouse_normal.x - target_position.x), 2) + Math.pow((mouse_normal.y - target_position.y), 2); + + // Animation direction + var source_to_target = source_loc < target_loc; + + // Change direction of points according to animation direction + if(!source_to_target){ + var new_edge_pts = []; + for(var i = edge_pts.length-1; i > 0; i=i-2){ + new_edge_pts.push(edge_pts[i-1], edge_pts[i]); + } + edge_pts = new_edge_pts; + } + + var starting_point = 0; + var minimum; + for(var i = 0; i < edge_pts.length-3; i=i+2){ + var a_b = Math.pow((mouse_normal.x-edge_pts[i]), 2) + Math.pow((mouse_normal.y-edge_pts[i+1]), 2); + a_b = Math.sqrt(a_b); + + var b_c = Math.pow((mouse_normal.x-edge_pts[i+2]), 2) + Math.pow((mouse_normal.y-edge_pts[i+3]), 2); + b_c = Math.sqrt(b_c); + + var a_c = Math.pow((edge_pts[i+2]-edge_pts[i]), 2) + Math.pow((edge_pts[i+3]-edge_pts[i+1]), 2); + a_c = Math.sqrt(a_c); + + var difference = Math.abs(a_c - a_b - b_c); + + if(minimum === undefined || minimum > difference){ + minimum = difference; + starting_point = i+2; + } + } + + var start_node = source_to_target ? source_node : target_node; + var s_normal = start_node.position(); + var s_rendered = start_node.renderedPosition(); + var zoom_level = cy.zoom(); + var finished = (edge_pts.length-starting_point-1)/2; + + // Animate for each bend point + for(var i = starting_point; i < edge_pts.length-1; i=i+2){ + // Convert normal position into rendered position + var rend_x = (edge_pts[i] - s_normal.x) * zoom_level + s_rendered.x; + var rend_y = (edge_pts[i+1] - s_normal.y) * zoom_level + s_rendered.y; + + cy.animate({ + duration: 700, + panBy: {x: (mouse_rend.x-rend_x), y: (mouse_rend.y-rend_y)}, + easing: 'ease', + complete: function(){ + finished--; + if(finished <= 0) + (source_to_target ? target_node : source_node).select(); + } + }); + } + + + +} + module.exports = appUtilities; From 22db9378e067519ce73004db195dcd7d65e063c9 Mon Sep 17 00:00:00 2001 From: metincansiper Date: Fri, 16 Feb 2018 11:29:34 -0800 Subject: [PATCH 08/97] Updating version of parallelshell #226 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1f1671980..7679a0211 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,6 @@ "express": "4.14.0", "browserify": "^11.2.0", "nodemon": "1.11.0", - "parallelshell": "^2.0.0" + "parallelshell": "^3.0.2" } } From 5d77ce36fa0295322f15092c5540a9f97881f988 Mon Sep 17 00:00:00 2001 From: Kaan Sancak Date: Wed, 21 Feb 2018 16:14:46 +0300 Subject: [PATCH 09/97] Implement selection and marquee zoom (#228) * Implement selection and marquee zoom * Fix requested changes Fix mode-handler bug Add disableMarqueeZoom * Fix bugs caused by disableMarqueeZoom * Bug fix and small change in marquue zoom feature --- app/img/toolbar/marquee.svg | 45 ++++++++++++++++++++++++++++ app/js/app-cy.js | 8 +++++ app/js/app-menu.js | 13 ++++++++ app/js/app-mode-handler.js | 59 +++++++++++++++++++++++++++++++++++-- app/js/app-utilities.js | 6 ++++ index.html | 10 +++++++ package.json | 2 +- 7 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 app/img/toolbar/marquee.svg diff --git a/app/img/toolbar/marquee.svg b/app/img/toolbar/marquee.svg new file mode 100644 index 000000000..5f9fd673c --- /dev/null +++ b/app/img/toolbar/marquee.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/js/app-cy.js b/app/js/app-cy.js index f56de1329..9ea5512ae 100644 --- a/app/js/app-cy.js +++ b/app/js/app-cy.js @@ -125,6 +125,14 @@ module.exports = function (chiseInstance) { }, coreAsWell: true // Whether core instance have this item on cxttap }, + { + id: 'ctx-menu-zoom-to-selected', + content: 'Zoom to Selected', + onClickFunction: function() { + $("#zoom-to-selected").trigger('click'); + }, + coreAsWell: true + }, { id: 'ctx-menu-expand', // ID of menu item content: 'Expand', // Title of menu item diff --git a/app/js/app-menu.js b/app/js/app-menu.js index 3deb7d79b..e65ace4f7 100644 --- a/app/js/app-menu.js +++ b/app/js/app-menu.js @@ -724,6 +724,15 @@ module.exports = function() { chiseInstance.expandAll(); }); + $("#zoom-to-selected").click( function(e){ + // use the active chise instance + var cy = appUtilities.getActiveCy(); + + var viewUtilities = cy.viewUtilities('get'); + + viewUtilities.zoomToSelected(cy.$(':selected')); + }); + $("#perform-layout, #perform-layout-icon").click(function (e) { // use active chise instance @@ -977,6 +986,10 @@ module.exports = function() { modeHandler.setSelectionMode(); }); + $('#marquee-zoom-mode-icon').click(function(e){ + modeHandler.setMarqueeZoomMode(); + }); + $('#add-node-mode-icon').click(function (e) { modeHandler.setAddNodeMode(); diff --git a/app/js/app-mode-handler.js b/app/js/app-mode-handler.js index 15286bffb..4fa8c0ec8 100644 --- a/app/js/app-mode-handler.js +++ b/app/js/app-mode-handler.js @@ -51,6 +51,11 @@ var modeHandler = { modeProperties.sustainMode = false; } + if(modeProperties.mode == "marquee-zoom-mode") { + var viewUtilities = cy.viewUtilities('get'); + viewUtilities.disableMarqueeZoom(); + } + if (modeProperties.mode != "add-node-mode") { cy.elements().unselect(); modeProperties.mode = "add-node-mode"; @@ -58,6 +63,7 @@ var modeHandler = { $('#select-mode-icon').parent().removeClass('selected-mode'); $('#add-edge-mode-icon').parent().removeClass('selected-mode'); $('#add-node-mode-icon').parent().addClass('selected-mode'); + $('#marquee-zoom-mode-icon').parent().removeClass('selected-mode'); $('.node-palette img').removeClass('inactive-palette-element'); $('.edge-palette img').addClass('inactive-palette-element'); @@ -87,7 +93,6 @@ var modeHandler = { // if the edgeType will remain same, add edge mode is already enabled and sustain mode is not set before, then set the sustain mode // so that users will be able to add the current edge type in a sustainable way. setAddEdgeMode: function (edgeType, language, _cy) { - // if _cy param is not set use the active cy instance var cy = _cy || appUtilities.getActiveCy(); @@ -107,6 +112,11 @@ var modeHandler = { modeProperties.sustainMode = false; } + if(modeProperties.mode == "marquee-zoom-mode") { + var viewUtilities = cy.viewUtilities('get'); + viewUtilities.disableMarqueeZoom(); + } + if (modeProperties.mode != "add-edge-mode") { cy.elements().unselect(); modeProperties.mode = "add-edge-mode"; @@ -114,6 +124,7 @@ var modeHandler = { $('#select-mode-icon').parent().removeClass('selected-mode'); $('#add-edge-mode-icon').parent().addClass('selected-mode'); $('#add-node-mode-icon').parent().removeClass('selected-mode'); + $('#marquee-zoom-mode-icon').parent().removeClass('selected-mode'); $('.node-palette img').addClass('inactive-palette-element'); $('.edge-palette img').removeClass('inactive-palette-element'); @@ -147,10 +158,16 @@ var modeHandler = { // access mode properties of the cy var modeProperties = appUtilities.getScratch(cy, 'modeProperties'); + if(modeProperties.mode == "marquee-zoom-mode") { + var viewUtilities = cy.viewUtilities('get') + viewUtilities.disableMarqueeZoom(); + } + if (modeProperties.mode != "selection-mode") { $('#select-mode-icon').parent().addClass('selected-mode'); $('#add-edge-mode-icon').parent().removeClass('selected-mode'); $('#add-node-mode-icon').parent().removeClass('selected-mode'); + $('#marquee-zoom-mode-icon').parent().removeClass('selected-mode'); $('.node-palette img').addClass('inactive-palette-element'); $('.edge-palette img').addClass('inactive-palette-element'); @@ -163,13 +180,51 @@ var modeHandler = { cy.autoungrabify(false); cy.autounselectify(false); } - $('.selected-mode-sustainable').removeClass('selected-mode-sustainable'); modeProperties.sustainMode = false; // reset mode properties of cy appUtilities.setScratch(cy, 'modeProperties', modeProperties); }, + // Set marquee zoom mode, disables sustainable mode. + setMarqueeZoomMode: function(_cy){ + // if _cy param is not set use the active cy instance + var cy = _cy || appUtilities.getActiveCy(); + + // access mode properties of the cy + var modeProperties = appUtilities.getScratch(cy, 'modeProperties'); + + if(modeProperties.mode != "marquee-zoom-mode"){ + $('#select-mode-icon').parent().removeClass('selected-mode'); + $('#add-edge-mode-icon').parent().removeClass('selected-mode'); + $('#add-node-mode-icon').parent().removeClass('selected-mode'); + $('#marquee-zoom-mode-icon').parent().addClass('selected-mode'); + $('.node-palette img').addClass('inactive-palette-element'); + $('.edge-palette img').addClass('inactive-palette-element'); + + modeProperties.mode = "marquee-zoom-mode"; + + var viewUtilities = cy.viewUtilities('get'); + + var setSelectionAfterAnimation = function(){ + modeHandler.setSelectionMode(cy); + viewUtilities.disableMarqueeZoom(); + } + + viewUtilities.enableMarqueeZoom(setSelectionAfterAnimation); + + cy.autoungrabify(false); + + $('.selected-mode-sustainable').removeClass('selected-mode-sustainable'); + modeProperties.sustainMode = false; + } + else{ + modeHandler.setSelectionMode(cy); + } + + // reset mode properties of cy + appUtilities.setScratch(cy, 'modeProperties', modeProperties); + }, autoEnableMenuItems: function (enable) { if (enable) { $("#expand-selected").parent("li").removeClass("disabled"); diff --git a/app/js/app-utilities.js b/app/js/app-utilities.js index 034179c7c..fcb478507 100644 --- a/app/js/app-utilities.js +++ b/app/js/app-utilities.js @@ -104,6 +104,7 @@ appUtilities.adjustUIComponents = function (_cy) { $('#add-node-mode-icon').parent().removeClass('selected-mode'); $('#add-edge-mode-icon').parent().removeClass('selected-mode-sustainable'); $('#add-node-mode-icon').parent().removeClass('selected-mode-sustainable'); + $('#marquee-zoom-mode-icon').parent().removeClass('selected-mode'); $('.node-palette img').addClass('inactive-palette-element'); $('.edge-palette img').addClass('inactive-palette-element'); $('.selected-mode-sustainable').removeClass('selected-mode-sustainable'); @@ -146,6 +147,11 @@ appUtilities.adjustUIComponents = function (_cy) { $('.edge-palette .selected-mode').addClass('selected-mode-sustainable'); } + } + else if( mode === 'marquee-zoom-mode'){ + + $('#marquee-zoom-mode-icon').parent().addClass('selected-mode'); + } // adjust status of grid guide related icons in toolbar diff --git a/index.html b/index.html index e6c8ed340..7619e2a65 100644 --- a/index.html +++ b/index.html @@ -151,6 +151,15 @@ + + @@ -568,10 +571,22 @@ + + + + + + @@ -613,7 +628,7 @@ --> - + + + + + + From 619ab6196efaa09c632a9be0b0107a42b9a09a51 Mon Sep 17 00:00:00 2001 From: leonarddrv Date: Mon, 7 May 2018 14:57:07 +0300 Subject: [PATCH 20/97] AF nodes transparancy changed #239 --- app/js/app-cy.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/js/app-cy.js b/app/js/app-cy.js index 63f9e39fb..ba6527b65 100644 --- a/app/js/app-cy.js +++ b/app/js/app-cy.js @@ -546,7 +546,9 @@ module.exports = function (chiseInstance) { var sbgnclasses = ['macromolecule', 'simple chemical', 'unspecified entity', 'nucleic acid feature', 'perturbing agent', 'source and sink', 'phenotype', 'process', 'omitted process', 'uncertain process', 'association', - 'dissociation', 'tag', 'and', 'or', 'not', 'delay']; + 'dissociation', 'tag', 'and', 'or', 'not', 'delay','BA plain', + 'BA unspecified entity', 'BA simple chemical', 'BA macromolecule', + 'BA nucleic acid feature', 'BA perturbing agent', 'BA complex']; for (i=0; i Date: Tue, 29 May 2018 11:07:17 +0300 Subject: [PATCH 21/97] Update team --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5df40de95..e7b8ad825 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,8 @@ Thanks to JetBrains for an [Open Source License](https://www.jetbrains.com/buy/o ## Team - * [Ilkin Safarli](https://github.com/kinimesi), [Hasan Balci](https://github.com/hasanbalci), [Leonard Dervishi](https://github.com/leonarddrv), [Istemi Bahceci](https://github.com/istemi-bahceci), and [Ugur Dogrusoz](https://github.com/ugurdogrusoz) of [i-Vis at Bilkent University](http://www.cs.bilkent.edu.tr/~ivis), [Metin Can Siper](https://github.com/metincansiper), [Ozgun Babur](https://github.com/ozgunbabur), and [Emek Demir](https://github.com/emekdemir) of the Demir Lab at [OHSU](http://www.ohsu.edu/), and [Ludovic Roy](https://github.com/royludo) and [Alexander Mazein](https://github.com/amazein) of [EISBM](http://eisbm.org) + * [Ilkin Safarli](https://github.com/kinimesi), [Hasan Balci](https://github.com/hasanbalci), [Leonard Dervishi](https://github.com/leonarddrv), [Ahmet Candiroglu](https://github.com/ahmetcandiroglu), [Kaan Sancak](https://github.com/kaansancak), and [Ugur Dogrusoz](https://github.com/ugurdogrusoz) of [i-Vis at Bilkent University](http://www.cs.bilkent.edu.tr/~ivis), [Metin Can Siper](https://github.com/metincansiper), [Ozgun Babur](https://github.com/ozgunbabur), and [Emek Demir](https://github.com/emekdemir) of the Demir Lab at [OHSU](http://www.ohsu.edu/), and [Alexander Mazein](https://github.com/amazein) of [EISBM](http://eisbm.org) #### Alumni - * Alper Karacelik, Selim Firat Yilmaz + * [Ludovic Roy](https://github.com/royludo), [Istemi Bahceci](https://github.com/istemi-bahceci), Alper Karacelik, Selim Firat Yilmaz From 12e5e596f81441c582defd0dfbb2ba4cdbb129e1 Mon Sep 17 00:00:00 2001 From: kinimesi Date: Tue, 29 May 2018 11:38:36 +0300 Subject: [PATCH 22/97] Updated jquery version. Fixes #253 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9bf106ee0..d808c35ae 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "cytoscape-undo-redo": "github:iVis-at-Bilkent/cytoscape.js-undo-redo#master", "cytoscape-view-utilities": "github:iVis-at-Bilkent/cytoscape.js-view-utilities#unstable", "filesaverjs": "~0.2.2", - "jquery": "~2.2.4", + "jquery": "~3.3.1", "jquery-expander": "1.7.0", "konva": "^1.6.3", "libxmljs": "^0.18.4", From b935383ccb241fb643974a15f950f2cf6c226a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6kberk=20Karaca?= Date: Tue, 29 May 2018 13:33:29 +0300 Subject: [PATCH 23/97] Change default sbgnml version to 0.2 (#254) --- app/js/app-menu.js | 6 +++--- index.html | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/js/app-menu.js b/app/js/app-menu.js index 1adb54011..02e680d21 100644 --- a/app/js/app-menu.js +++ b/app/js/app-menu.js @@ -845,11 +845,11 @@ module.exports = function() { $("#save-as-sbgnml, #save-icon").click(function (evt) { //var filename = document.getElementById('file-name').innerHTML; //chise.saveAsSbgnml(filename); - fileSaveView.render("sbgnml", "0.3"); + fileSaveView.render("sbgnml", "0.2"); }); - $("#export-as-sbgnml2-file").click(function (evt) { - fileSaveView.render("sbgnml", "0.2"); + $("#export-as-sbgnml3-file").click(function (evt) { + fileSaveView.render("sbgnml", "0.3"); }); $("#add-complex-for-selected").click(function (e) { diff --git a/index.html b/index.html index e560a6e6a..0217b38a4 100644 --- a/index.html +++ b/index.html @@ -91,7 +91,7 @@ From 91c395e7b9266456ab60c18ca989aee6a6b4f641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6kberk=20Karaca?= Date: Tue, 29 May 2018 16:59:13 +0300 Subject: [PATCH 24/97] Implement celldesginer file import and export features under File menu (#248) Resolves #242 --- app/js/app-menu.js | 54 +++++++++++++++++++++++++++++++++++++++- app/js/backbone-views.js | 9 ++++++- index.html | 1 + 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/app/js/app-menu.js b/app/js/app-menu.js index 02e680d21..4763f7817 100644 --- a/app/js/app-menu.js +++ b/app/js/app-menu.js @@ -32,6 +32,33 @@ module.exports = function() { } }); } + + function cd2sbgnml(xml) { + + $.ajax({ + type: 'post', + url: "http://localhost:4567/cd2sbgnml", + data: {xml: xml}, + success: function (data) { + var chiseInstance = appUtilities.getActiveChiseInstance(); + validateSBGNML(xml); + chiseInstance.loadSBGNMLText(data); + chiseInstance.endSpinner("load-spinner"); + } + }) + } + + function sbgnml2cd(xml) { + + $.ajax({ + type: 'post', + url: "http://localhost:4567/sbgnml2cd", + data: {xml: xml}, + success: function (data) { + fileSaveView.render("celldesigner", null, data); + } + }) + } function loadSample(filename) { @@ -258,9 +285,28 @@ module.exports = function() { } }); + $('#import-celldesigner-file').click(function (){ + $("#celldesigner-file-input").trigger('click'); + }); + + $('#celldesigner-file-input').change(function (e, fileObject) { + + if ($(this).val() != "" || fileObject) { + var file = this.files[0] || fileObject; + appUtilities.setFileContent(file.name); + var reader = new FileReader(); + reader.onload = function(event) { + chiseInstance = appUtilities.getActiveChiseInstance(); + chiseInstance.startSpinner("load-spinner"); + cd2sbgnml(event.target.result); + }; + reader.readAsText(file); + } + }); + $("#import-simple-af-file").click(function () { $("#simple-af-file-input").trigger('click'); - }); + }); $("#simple-af-file-input").change(function () { var chiseInstance = appUtilities.getActiveChiseInstance(); @@ -851,6 +897,12 @@ module.exports = function() { $("#export-as-sbgnml3-file").click(function (evt) { fileSaveView.render("sbgnml", "0.3"); }); + + $("#export-as-celldesigner-file").click(function (evt) { + var chiseInstance = appUtilities.getActiveChiseInstance(); + var sbgnml = chiseInstance.createSbgnml(); + sbgnml2cd(sbgnml); + }); $("#add-complex-for-selected").click(function (e) { diff --git a/app/js/backbone-views.js b/app/js/backbone-views.js index ea2e5346c..1eb477beb 100644 --- a/app/js/backbone-views.js +++ b/app/js/backbone-views.js @@ -2,6 +2,7 @@ var jquery = $ = require('jquery'); var _ = require('underscore'); var Backbone = require('backbone'); var chroma = require('chroma-js'); +var FileSaver = require('filesaverjs'); var appUtilities = require('./app-utilities'); var setFileContent = appUtilities.setFileContent.bind(appUtilities); @@ -1462,7 +1463,7 @@ var FileSaveView = Backbone.View.extend({ fileformat: sbgnml version: for sbgnml: 0.2, 0.3 */ - render: function (fileformat, version) { + render: function (fileformat, version, text) { var self = this; self.template = _.template($("#file-save-template").html()); @@ -1498,6 +1499,12 @@ var FileSaveView = Backbone.View.extend({ delete properties.mapType; // already stored in sbgn file, no need to store in extension as property chiseInstance.saveAsSbgnml(filename, version, renderInfo, properties); } + else if(fileformat === "celldesigner") { + var blob = new Blob([text], { + type: "text/plain;charset=utf-8;", + }); + FileSaver.saveAs(blob, filename); + } else { // invalid file format provided console.error("FileSaveView received unsupported file format: "+fileformat); } diff --git a/index.html b/index.html index 0217b38a4..b8ab53730 100644 --- a/index.html +++ b/index.html @@ -81,6 +81,7 @@ From 8d7d1b2468ffe0f3916e3afca24b3794371144ea Mon Sep 17 00:00:00 2001 From: kinimesi Date: Wed, 30 May 2018 13:05:43 +0300 Subject: [PATCH 25/97] Changed cd2sbgnml service url --- app/js/app-menu.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/js/app-menu.js b/app/js/app-menu.js index 4763f7817..412267bfc 100644 --- a/app/js/app-menu.js +++ b/app/js/app-menu.js @@ -37,7 +37,7 @@ module.exports = function() { $.ajax({ type: 'post', - url: "http://localhost:4567/cd2sbgnml", + url: "http://web.newteditor.org:8080/cd2sbgnml", data: {xml: xml}, success: function (data) { var chiseInstance = appUtilities.getActiveChiseInstance(); @@ -52,7 +52,7 @@ module.exports = function() { $.ajax({ type: 'post', - url: "http://localhost:4567/sbgnml2cd", + url: "http://web.newteditor.org:8080/sbgnml2cd", data: {xml: xml}, success: function (data) { fileSaveView.render("celldesigner", null, data); From 54d8841e71cc942067647df78836b3ffc04a375b Mon Sep 17 00:00:00 2001 From: Kaan Sancak Date: Wed, 30 May 2018 14:52:17 +0300 Subject: [PATCH 26/97] Implement Reversible Reactions Template (#255) * Add Reversible Reactions Template UI * Add reversible reactions support * Fix indentation --- app/css/chise.css | 8 ++ app/js/backbone-views.js | 234 ++++++++++++++++++++++++++++----------- index.html | 39 ++++++- 3 files changed, 210 insertions(+), 71 deletions(-) diff --git a/app/css/chise.css b/app/css/chise.css index f07d2e8fd..e19efc5e8 100644 --- a/app/css/chise.css +++ b/app/css/chise.css @@ -742,6 +742,14 @@ img#template-reaction-add-button:hover { cursor: pointer; } +img#template-reversible-input-add-button:hover { + cursor: pointer; +} + +img#template-reversible-output-add-button:hover { + cursor: pointer; +} + .pointer-button:hover { cursor: pointer; } diff --git a/app/js/backbone-views.js b/app/js/backbone-views.js index 1eb477beb..a7761e169 100644 --- a/app/js/backbone-views.js +++ b/app/js/backbone-views.js @@ -423,7 +423,7 @@ var MapTabGeneralPanel = GeneralPropertiesParentView.extend({ self.params.inferNestingOnLoad = {id: "infer-nesting-on-load", type: "checkbox", property: "currentGeneralProperties.inferNestingOnLoad"}; - + self.params.enablePorts = {id: "enable-ports", type: "checkbox", property: "currentGeneralProperties.enablePorts", update: self.applyUpdate}; @@ -498,7 +498,7 @@ var MapTabGeneralPanel = GeneralPropertiesParentView.extend({ cy.undoRedo().do("changeMenu", self.params.allowCompoundNodeResize); $('#allow-compound-node-resize').blur(); }); - + $(document).on("change", "#infer-nesting-on-load", function (evt) { // use active cy instance @@ -899,7 +899,7 @@ var NeighborhoodQueryView = Backbone.View.extend({ var currentGeneralProperties = appUtilities.getScratch(cy, 'currentGeneralProperties'); var currentInferNestingOnLoad = currentGeneralProperties.inferNestingOnLoad; - + $.ajax({ url: queryURL, type: 'GET', @@ -1419,7 +1419,7 @@ var PathsByURIQueryView = Backbone.View.extend({ So this PromptSaveView isn't used for now, replaced by PromptConfirmationView. */ var PromptSaveView = Backbone.View.extend({ - + initialize: function () { var self = this; self.template = _.template($("#prompt-save-template").html()); @@ -1436,12 +1436,12 @@ var PromptSaveView = Backbone.View.extend({ afterFunction(); $(self.el).modal('toggle'); }); - + $(document).off("click", "#prompt-save-reject").on("click", "#prompt-save-reject", function (evt) { afterFunction(); $(self.el).modal('toggle'); }); - + $(document).off("click", "#prompt-save-cancel").on("click", "#prompt-save-cancel", function (evt) { $(self.el).modal('toggle'); }); @@ -1469,13 +1469,13 @@ var FileSaveView = Backbone.View.extend({ $(self.el).html(self.template); $(self.el).modal('show'); - + $("#file-save-table").keyup(function(e){ if (e.which == 13 && $(self.el).data('bs.modal').isShown && !$("#file-save-accept").is(":focus") && !$("#file-save-cancel").is(":focus")){ $("#file-save-accept").click(); } }); - + var filename = document.getElementById('file-name').innerHTML; $("#file-save-filename").val(filename); @@ -1681,11 +1681,11 @@ var PromptInvalidFileView = Backbone.View.extend({ $(self.el).html(self.template); $(self.el).modal('show'); - + $(document).off("click", "#prompt-invalidFile-confirm").on("click", "#prompt-invalidFile-confirm", function (evt) { $(self.el).modal('toggle'); }); - + return this; } }); @@ -1701,32 +1701,62 @@ var PromptInvalidURLWarning = Backbone.View.extend({ $(self.el).html(self.template); $(self.el).modal('show'); - + $(document).off("click", "#prompt-invalidURL-confirm").on("click", "#prompt-invalidURL-confirm", function (evt) { $(self.el).modal('toggle'); }); - + return this; } }); var ReactionTemplateView = Backbone.View.extend({ - addMacromolecule: function (i) { + addMacromolecule: function (type, i) { var html = "
" + "" - + "
Infer Nesting on Load @@ -1682,6 +1682,7 @@
+ + + + + + + +
+ + +
+ +
+ + + + + + + + + +
+ + +
+ +
+ + From 834e68ca24e7e9456824ec059c44090b4b0006c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6kberk=20Karaca?= Date: Wed, 30 May 2018 15:35:55 +0300 Subject: [PATCH 27/97] Set file extension properly for celldesigner export --- app/js/backbone-views.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/js/backbone-views.js b/app/js/backbone-views.js index a7761e169..05d6e953c 100644 --- a/app/js/backbone-views.js +++ b/app/js/backbone-views.js @@ -1477,6 +1477,8 @@ var FileSaveView = Backbone.View.extend({ }); var filename = document.getElementById('file-name').innerHTML; + if (fileformat === "celldesigner") + filename = filename.substring(0, filename.lastIndexOf('.')).concat(".xml"); $("#file-save-filename").val(filename); $(document).off("click", "#file-save-accept").on("click", "#file-save-accept", function (evt) { From aa2c64e49cfe9218cb7c56a0fa0b3f629e559903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6kberk=20Karaca?= Date: Wed, 30 May 2018 15:53:56 +0300 Subject: [PATCH 28/97] Export files in plain SBGN-ML format (#258) * Add an option to UI to export SBGN-ML Plain file * Give undefined parameters for extensions to sbgnviz if sbgn version is plain * Change order of items under export menu * Change parameter of plain export --- app/js/app-menu.js | 4 ++++ app/js/backbone-views.js | 8 +++++++- index.html | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/js/app-menu.js b/app/js/app-menu.js index 412267bfc..65900732b 100644 --- a/app/js/app-menu.js +++ b/app/js/app-menu.js @@ -904,6 +904,10 @@ module.exports = function() { sbgnml2cd(sbgnml); }); + $("#export-as-sbgnml-plain-file").click(function (evt) { + fileSaveView.render("sbgnml", "plain"); + }); + $("#add-complex-for-selected").click(function (e) { // use active chise instance diff --git a/app/js/backbone-views.js b/app/js/backbone-views.js index 05d6e953c..d4eca8633 100644 --- a/app/js/backbone-views.js +++ b/app/js/backbone-views.js @@ -1499,7 +1499,13 @@ var FileSaveView = Backbone.View.extend({ var renderInfo = appUtilities.getAllStyles(); var properties = jquery.extend(true, {}, currentGeneralProperties); delete properties.mapType; // already stored in sbgn file, no need to store in extension as property - chiseInstance.saveAsSbgnml(filename, version, renderInfo, properties); + // Exclude extensions if the version is plain + if (version === "plain") { + chiseInstance.saveAsSbgnml(filename, version); + } + else { + chiseInstance.saveAsSbgnml(filename, version, renderInfo, properties); + } } else if(fileformat === "celldesigner") { var blob = new Blob([text], { diff --git a/index.html b/index.html index 0e6145eb1..7339fa7be 100644 --- a/index.html +++ b/index.html @@ -92,6 +92,7 @@ From 94d2749267603af7fe3ec289aa0930f8da76fdcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6kberk=20Karaca?= Date: Thu, 31 May 2018 13:23:50 +0300 Subject: [PATCH 29/97] Implement PromptFileConversionErrorView --- app/js/app-menu.js | 37 +++++++++++++++++++++++++++++++++---- app/js/backbone-views.js | 22 ++++++++++++++++++++++ index.html | 31 +++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 4 deletions(-) diff --git a/app/js/app-menu.js b/app/js/app-menu.js index 65900732b..63f4dde74 100644 --- a/app/js/app-menu.js +++ b/app/js/app-menu.js @@ -12,7 +12,7 @@ module.exports = function() { var dynamicResize = appUtilities.dynamicResize.bind(appUtilities); var layoutPropertiesView, generalPropertiesView, neighborhoodQueryView, pathsBetweenQueryView, pathsFromToQueryView, commonStreamQueryView, pathsByURIQueryView, promptSaveView, promptConfirmationView, - promptMapTypeView, promptInvalidFileView, promptInvalidURIWarning, reactionTemplateView, gridPropertiesView, fontPropertiesView, fileSaveView; + promptMapTypeView, promptInvalidFileView, promptFileConversionErrorView, promptInvalidURIWarning, reactionTemplateView, gridPropertiesView, fontPropertiesView, fileSaveView; function validateSBGNML(xml) { $.ajax({ @@ -37,13 +37,33 @@ module.exports = function() { $.ajax({ type: 'post', - url: "http://web.newteditor.org:8080/cd2sbgnml", + url: "http://localhost:8080/cd2sbgnml", data: {xml: xml}, success: function (data) { var chiseInstance = appUtilities.getActiveChiseInstance(); + var cy = appUtilities.getActiveCy(); validateSBGNML(xml); - chiseInstance.loadSBGNMLText(data); chiseInstance.endSpinner("load-spinner"); + if (cy.elements().length !== 0) { + promptConfirmationView.render(function() { + chiseInstance.loadSBGNMLText(data); + }); + } + else { + chiseInstance.loadSBGNMLText(data); + } + }, + error: function (XMLHttpRequest) { + var chiseInstance = appUtilities.getActiveChiseInstance(); + + if (XMLHttpRequest.status === 0) { + console.log("Conversion service is not available"); + } + else { + console.log("Conversion failed"); + } + promptFileConversionErrorView.render(); + chiseInstance.endSpinner("load-spinner"); } }) } @@ -52,10 +72,18 @@ module.exports = function() { $.ajax({ type: 'post', - url: "http://web.newteditor.org:8080/sbgnml2cd", + url: "http://localhost:8080/sbgnml2cd", data: {xml: xml}, success: function (data) { fileSaveView.render("celldesigner", null, data); + }, + error: function (XMLHttpRequest) { + if (XMLHttpRequest.status === 0) { + console.log("Conversion service is not available"); + } + else { + console.log("Conversion failed"); + } } }) } @@ -92,6 +120,7 @@ module.exports = function() { promptConfirmationView = appUtilities.promptConfirmationView = new BackboneViews.PromptConfirmationView({el: '#prompt-confirmation-table'}); promptMapTypeView = appUtilities.promptMapTypeView = new BackboneViews.PromptMapTypeView({el: '#prompt-mapType-table'}); promptInvalidFileView = appUtilities.promptInvalidFileView = new BackboneViews.PromptInvalidFileView({el: '#prompt-invalidFile-table'}); + promptFileConversionErrorView = appUtilities.promptFileConversionErrorView = new BackboneViews.PromptFileConversionErrorView({el: '#prompt-fileConversionError-table'}); reactionTemplateView = appUtilities.reactionTemplateView = new BackboneViews.ReactionTemplateView({el: '#reaction-template-table'}); gridPropertiesView = appUtilities.gridPropertiesView = new BackboneViews.GridPropertiesView({el: '#grid-properties-table'}); fontPropertiesView = appUtilities.fontPropertiesView = new BackboneViews.FontPropertiesView({el: '#font-properties-table'}); diff --git a/app/js/backbone-views.js b/app/js/backbone-views.js index d4eca8633..c6763b4c7 100644 --- a/app/js/backbone-views.js +++ b/app/js/backbone-views.js @@ -1698,6 +1698,27 @@ var PromptInvalidFileView = Backbone.View.extend({ } }); +var PromptFileConversionErrorView = Backbone.View.extend({ + initialize: function () { + var self = this; + self.template = _.template($("#prompt-fileConversionError-template").html()); + }, + render: function() { + console.log("Rendering file conversion error view"); + var self = this; + self.template = _.template($("#prompt-fileConversionError-template").html()); + + $(self.el).html(self.template); + $(self.el).modal('show'); + + $(document).off("click", "#prompt-fileConversionError-confirm").on("click", "#prompt-fileConversionError-confirm", function (evt) { + $(self.el).modal('toggle'); + }); + + return this; + } +}); + var PromptInvalidURLWarning = Backbone.View.extend({ initialize: function () { var self = this; @@ -2444,6 +2465,7 @@ module.exports = { PromptConfirmationView: PromptConfirmationView, PromptMapTypeView: PromptMapTypeView, PromptInvalidFileView: PromptInvalidFileView, + PromptFileConversionErrorView: PromptFileConversionErrorView, ReactionTemplateView: ReactionTemplateView, GridPropertiesView: GridPropertiesView, FontPropertiesView: FontPropertiesView, diff --git a/index.html b/index.html index 7339fa7be..65c82af1e 100644 --- a/index.html +++ b/index.html @@ -1633,6 +1633,37 @@ + + + + + + + + + From 0b22d9e6f5b1fd681330cbd5f213897dccd8539f Mon Sep 17 00:00:00 2001 From: leonarddrv Date: Mon, 11 Jun 2018 12:23:37 +0300 Subject: [PATCH 57/97] Changed CHEBI ID #268 --- app/js/backbone-views.js | 2 +- index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/js/backbone-views.js b/app/js/backbone-views.js index 416be75b1..c76a563b6 100644 --- a/app/js/backbone-views.js +++ b/app/js/backbone-views.js @@ -189,7 +189,7 @@ var ChemicalView = Backbone.View.extend({ var variables = { chemicalDescription: this.model.description[0], chebiName: this.model.label, - chebiID: this.model.obo_id + chebiID: this.model.obo_id.substring(6, this.model.obo_id.length) //Gets only the nr from ChEBI:15422 format }; // compile the template using underscore diff --git a/index.html b/index.html index 7a1a919c7..582591178 100644 --- a/index.html +++ b/index.html @@ -2195,7 +2195,7 @@ ChEBI ID: - + <%=chebiID %> From cd0b41e9cc76c5de3a632ca10e7de60fc3e94044 Mon Sep 17 00:00:00 2001 From: leonarddrv Date: Mon, 11 Jun 2018 13:17:58 +0300 Subject: [PATCH 58/97] Properties from ChEBI changed #268 --- app/js/fill-biogene-container.js | 2 +- app/js/fill-chemical-container.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/js/fill-biogene-container.js b/app/js/fill-biogene-container.js index 81840d8d8..6775bd2ee 100644 --- a/app/js/fill-biogene-container.js +++ b/app/js/fill-biogene-container.js @@ -56,7 +56,7 @@ var fillBioGeneContainer = function (node) { })).render(); } else { - $('#biogene-container').html("No additional information available for the selected node!"); + $('#biogene-container').html("No additional information available for the selected node!"); } }, function (xhr, status, error) { $('#biogene-container').html("Error retrieving data: " + error + ""); diff --git a/app/js/fill-chemical-container.js b/app/js/fill-chemical-container.js index da2116fd5..73c5f92a9 100644 --- a/app/js/fill-chemical-container.js +++ b/app/js/fill-chemical-container.js @@ -16,7 +16,7 @@ var fillChemicalContainer = function (node) { if (geneName == "" || geneName == undefined) { $('#chemical-title').html("" + node.data('label') + ""); - $('#chemical-container').html("No additional information available for the selected node!"); + $('#chemical-container').html("No additional information available for the selected node!"); return; } @@ -46,7 +46,7 @@ var fillChemicalContainer = function (node) { })).render(); } else { - $('#chemical-container').html("No additional information available for the selected node!"); + $('#chemical-container').html("No additional information available for the selected node!"); } }, function (xhr, status, error) { From b97adc218ba864c02f11554d199a27dcde5411d8 Mon Sep 17 00:00:00 2001 From: leonarddrv Date: Mon, 11 Jun 2018 16:33:01 +0300 Subject: [PATCH 59/97] Query dialog improvements #281 --- app/js/backbone-views.js | 6 +++++- index.html | 7 ++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/js/backbone-views.js b/app/js/backbone-views.js index c76a563b6..142c9deee 100644 --- a/app/js/backbone-views.js +++ b/app/js/backbone-views.js @@ -920,7 +920,7 @@ var NeighborhoodQueryView = Backbone.View.extend({ new PromptInvalidQueryView({el: '#prompt-invalidQuery-table'}).render(); return; } - if (self.currentQueryParameters.lengthLimit > 3) { + if (self.currentQueryParameters.lengthLimit > 2) { $(self.el).modal('toggle'); new PromptInvalidLengthLimitView({el: '#prompt-invalidLengthLimit-table'}).render(); document.getElementById("query-neighborhood-length-limit").focus(); @@ -1674,6 +1674,10 @@ var PromptInvalidLengthLimitView = Backbone.View.extend({ self.template = _.template($("#prompt-invalidLengthLimit-template").html()); $(self.el).html(self.template); + if (PCdialog == "Neighborhood") + document.getElementById("length-limit-constant").innerHTML = "Length limit can be at most 2."; + else + document.getElementById("length-limit-constant").innerHTML = "Length limit can be at most 3."; $(self.el).modal('show'); $(document).off("click", "#prompt-invalidLengthLimit-confirm").on("click", "#prompt-invalidLengthLimit-confirm", function (evt) { diff --git a/index.html b/index.html index 582591178..e88c79018 100644 --- a/index.html +++ b/index.html @@ -1183,7 +1183,8 @@ - Find the neighbors of an entity within a certain distance. + + Find the neighbors of an entity within a certain distance               @@ -1274,7 +1275,7 @@ - @@ -1564,7 +1565,7 @@ From 735d9be2cd18d54631dafdfe2c2fd11f5399c353 Mon Sep 17 00:00:00 2001 From: kaansancak Date: Tue, 12 Jun 2018 00:59:00 +0300 Subject: [PATCH 60/97] Implement interactive relocation of info-boxes #265 --- app/js/app-cy.js | 9 ++ app/js/app-menu.js | 21 +-- app/js/app-utilities.js | 294 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 314 insertions(+), 10 deletions(-) diff --git a/app/js/app-cy.js b/app/js/app-cy.js index e491dd6d7..509413099 100644 --- a/app/js/app-cy.js +++ b/app/js/app-cy.js @@ -229,6 +229,15 @@ module.exports = function (chiseInstance) { ur.do("convertIntoReversibleReaction", {processId: cyTarget.id(), collection: consumptionEdges, mapType: "Unknown"}); } } + }, + { + id: 'ctx-menu-relocate-info-boxes', + content: 'Relocate Info Boxes', + selector: 'node', + onClickFunction: function (event){ + var cyTarget = event.target || event.cyTarget; + appUtilities.relocateInfoBoxes(cyTarget); + } } ]); diff --git a/app/js/app-menu.js b/app/js/app-menu.js index 449d750c0..6efc18810 100644 --- a/app/js/app-menu.js +++ b/app/js/app-menu.js @@ -80,7 +80,7 @@ module.exports = function() { } }) } - + function loadSample(filename) { // use the active chise instance @@ -283,7 +283,7 @@ module.exports = function() { }); $("#file-input").change(function (e, fileObject) { - + // use the active chise instance var chiseInstance = appUtilities.getActiveChiseInstance(); @@ -294,7 +294,7 @@ module.exports = function() { var file = this.files[0] || fileObject; var loadCallbackSBGNMLValidity = function (text) { validateSBGNML(text); - } + } var loadCallbackInvalidityWarning = function () { promptInvalidFileView.render(); } @@ -340,7 +340,7 @@ module.exports = function() { var loadCallbackInvalidityWarning = function () { promptInvalidFileView.render(); } - + if ($(this).val() != "") { var file = this.files[0]; @@ -461,9 +461,9 @@ module.exports = function() { e.preventDefault(); $("#about_modal").modal('show'); }); - + $(".title").click(function(e){ - e.stopPropagation(); + e.stopPropagation(); }); var selectorToSampleFileName = { @@ -493,7 +493,7 @@ module.exports = function() { promptConfirmationView.render(function(){loadSample(selectorToSampleFileName[selector])}); } else { - loadSample(selectorToSampleFileName[selector]); + loadSample(selectorToSampleFileName[selector]); } }); })(selector); @@ -525,7 +525,7 @@ module.exports = function() { cy.elements().unselect(); cy.edges().select(); }); - + $("#hide-selected, #hide-selected-icon").click(function(e) { // use active cy instance @@ -608,7 +608,7 @@ module.exports = function() { $("#highlight-search-menu-item").click(function (e) { $("#search-by-label-text-box").focus(); }); - + $("#highlight-selected, #highlight-selected-icon").click(function (e) { // use active chise instance @@ -920,7 +920,7 @@ module.exports = function() { $("#export-as-sbgnml3-file").click(function (evt) { fileSaveView.render("sbgnml", "0.3"); }); - + $("#export-as-celldesigner-file").click(function (evt) { var chiseInstance = appUtilities.getActiveChiseInstance(); var sbgnml = chiseInstance.createSbgnml(); @@ -1097,6 +1097,7 @@ module.exports = function() { $(document).on('mouseup', function (e) { dragAndDropPlacement = false; appUtilities.removeDragImage(); + appUtilities.disableInfoBoxRelocationDrag(); }); $('#select-mode-icon').click(function (e) { diff --git a/app/js/app-utilities.js b/app/js/app-utilities.js index 4a3423d34..5a6b6fea9 100644 --- a/app/js/app-utilities.js +++ b/app/js/app-utilities.js @@ -2228,4 +2228,298 @@ appUtilities.navigateToOtherEnd = function(edge, mouse_rend, mouse_normal) { } +//Info-box drag handlers +var relocationDragHandler; +var relocationHandler; + +//Enables info-box relocation if a node is selected +appUtilities.relocateInfoBoxes = function(node){ + //Abort if node has no info-boxes or selected ele is not a node + if (node.data("auxunitlayouts") === undefined || !node.isNode()) { + return; + } + node.unselect(); + this.enableInfoBoxRelocation(node); +} + +//Checks whether a info-box is selected in a given mouse position +appUtilities.checkMouseContainsInfoBox = function(unit, mouse_down_x, mouse_down_y){ + var box = unit.bbox; + var instance = this.getActiveSbgnvizInstance(); + var cy = this.getActiveCy(); + var coords = instance.classes.AuxiliaryUnit.getAbsoluteCoord(unit, cy); + var x_loc = coords.x; + var y_loc = coords.y; + var width = box.w; + var height = box.h; + return ((mouse_down_x >= x_loc - width / 2) && (mouse_down_x <= x_loc + width / 2)) + && ( (mouse_down_y >= y_loc - height / 2) && (mouse_down_y <= y_loc + height / 2)); +} + +//Enables info-box relocationHandler +appUtilities.enableInfoBoxRelocation = function(node){ + var cy = this.getActiveCy(); + //Disable box movements + var selectedBox; + var anchorSide; + cy.autounselectify(true); + cy.on('mousedown', relocationHandler = function(event){ + //Check whether event contained by infobox of a node + //Lock the node so that it won't change position when + //Info boxes are dragged + cy.autolock(true); + var top = node.data('auxunitlayouts').top; + var bottom = node.data('auxunitlayouts').bottom; + var right = node.data('auxunitlayouts').right; + var left = node.data('auxunitlayouts').left; + + //Get mouse positions + var mouse_down_x = event.position.x; + var mouse_down_y = event.position.y; + var instance = appUtilities.getActiveSbgnvizInstance(); + + var oldAnchorSide; //Hold old anchor side to modify units + //Check top units + if (top !== undefined && selectedBox === undefined) { + var units = top.units; + for (var i = units.length-1; i >= 0 ; i--) { + if (appUtilities.checkMouseContainsInfoBox(units[i], mouse_down_x, mouse_down_y)) { + selectedBox = units[i]; + oldAnchorSide = selectedBox.anchorSide; + break; + } + } + } + //Check right units + if (right !== undefined && selectedBox === undefined) { + var units = right.units; + for (var i = units.length-1; i >= 0 ; i--) { + if (appUtilities.checkMouseContainsInfoBox(units[i], mouse_down_x, mouse_down_y)) { + selectedBox = units[i]; + oldAnchorSide = selectedBox.anchorSide; + break; + } + } + } + //Check bottom units + if (bottom !== undefined && selectedBox === undefined) { + var units = bottom.units; + for (var i = units.length-1; i >= 0 ; i--) { + if (appUtilities.checkMouseContainsInfoBox(units[i], mouse_down_x, mouse_down_y)) { + selectedBox = units[i]; + oldAnchorSide = selectedBox.anchorSide; + break; + } + } + } + //Check left units + if (left !== undefined && selectedBox === undefined) { + var units = left.units; + for (var i = units.length-1; i >= 0 ; i--) { + if (appUtilities.checkMouseContainsInfoBox(units[i], mouse_down_x, mouse_down_y)) { + selectedBox = units[i]; + oldAnchorSide = selectedBox.anchorSide; + break; + } + } + } + + //If no info-box found abort + if (selectedBox === undefined) { + appUtilities.disableInfoBoxRelocation(); + return; + } + //Else If a info-box contained by event move info-box + var instance = appUtilities.getActiveSbgnvizInstance(); + var parentBbox = node.data("bbox"); + var position = node._private.position; + selectedBox.dashed = true; + var last_mouse_x = mouse_down_x; + var last_mouse_y = mouse_down_y; + + cy.on("mousemove", relocationDragHandler = function(event){ + if (selectedBox === undefined) { + appUtilities.disableInfoBoxRelocation(); + return; + } + var drag_x = event.position.x; + var drag_y = event.position.y; + var anchorSide = selectedBox.anchorSide; + + var gap; + var shift_x; + var shift_y; + var box_new_x; + var box_new_y; + + //If anchor side is top or bottom only move in x direction + if (anchorSide === "top" || anchorSide === "bottom") { + if (anchorSide === "top") { + gap = instance.classes.AuxUnitLayout.getCurrentTopGap(); + } + else { + gap = instance.classes.AuxUnitLayout.getCurrentBottomGap(); + } + + shift_x = drag_x - last_mouse_x; + box_new_x = selectedBox.bbox.x + shift_x; //Calculate new box position + //Get absolute position + var absoluteCoords = instance.classes.AuxiliaryUnit.convertToAbsoluteCoord(selectedBox, box_new_x, selectedBox.bbox.y, cy); + var newRelativeCoords; + if (absoluteCoords.x - selectedBox.bbox.w/2 < (position.x - parentBbox.w/2) + gap) { //Box cannot go futher than parentBox + margin on left side + newRelativeCoords = instance.classes.AuxiliaryUnit.convertToRelativeCoord(selectedBox,((position.x - parentBbox.w/2) + gap + selectedBox.bbox.w/2), + absoluteCoords.y, cy); + selectedBox.bbox.x = newRelativeCoords.x; + } + else if (absoluteCoords.x + selectedBox.bbox.w/2 > (position.x + parentBbox.w/2) - gap) { //Box cannot go futher than parentBox - margin on right side + newRelativeCoords = instance.classes.AuxiliaryUnit.convertToRelativeCoord(selectedBox, ((position.x + parentBbox.w/2) - gap - selectedBox.bbox.w/2), + absoluteCoords.y, cy); + selectedBox.bbox.x = newRelativeCoords.x; + } + else { //Else it is already relative + selectedBox.bbox.x = box_new_x; + } + //If box is at margin points allow it to change anchor side + //If it on left it can pass left anchor side + absoluteCoords = instance.classes.AuxiliaryUnit.convertToAbsoluteCoord(selectedBox, selectedBox.bbox.x, selectedBox.bbox.y, cy); //Get current absolute coords + if (absoluteCoords.x === (position.x - parentBbox.w/2) + gap + selectedBox.bbox.w/2) { //If it is on the left margin allow it to change anchor sides + //If it is in the top and mouse moves bottom it can go left anchor + if (last_mouse_y < drag_y && anchorSide === "top") { + selectedBox.anchorSide = "left"; //Set new anchor side + newRelativeCoords = instance.classes.AuxiliaryUnit.convertToRelativeCoord(selectedBox, (position.x - parentBbox.w/2), + (position.y - parentBbox.h/2 + instance.classes.AuxUnitLayout.getCurrentLeftGap()), cy); + selectedBox.bbox.x = newRelativeCoords.x; + selectedBox.bbox.y = newRelativeCoords.y; + } + else if (last_mouse_y > drag_y && anchorSide === "bottom") { //If it is in the bottom and mouse moves up it can go left anchor side + selectedBox.anchorSide = "left"; //Set new anchor side + newRelativeCoords = instance.classes.AuxiliaryUnit.convertToRelativeCoord(selectedBox, (position.x - parentBbox.w/2), + (position.y + parentBbox.h/2 - instance.classes.AuxUnitLayout.getCurrentLeftGap()), cy); + selectedBox.bbox.x = newRelativeCoords.x; + selectedBox.bbox.y = newRelativeCoords.y; + } + } + //If it on right it can pass right anchor side, * 2 for relaxation + else if (absoluteCoords.x === (position.x + parentBbox.w/2) - gap - selectedBox.bbox.w/2) { + if (last_mouse_y < drag_y && anchorSide === "top") { + selectedBox.anchorSide = "right"; //Set new anchor side + newRelativeCoords = instance.classes.AuxiliaryUnit.convertToRelativeCoord(selectedBox, (position.x + parentBbox.w/2), + (position.y - parentBbox.h/2 + instance.classes.AuxUnitLayout.getCurrentRightGap()), cy); + selectedBox.bbox.x = newRelativeCoords.x; + selectedBox.bbox.y = newRelativeCoords.y; + } + else if (last_mouse_y > drag_y && anchorSide === "bottom") { //If it is in the bottom and mouse moves up it can go left anchor side + selectedBox.anchorSide = "right"; //Set new anchor side + newRelativeCoords = instance.classes.AuxiliaryUnit.convertToRelativeCoord(selectedBox, (position.x + parentBbox.w/2), + (position.y + parentBbox.h/2 - instance.classes.AuxUnitLayout.getCurrentRightGap()), cy); + selectedBox.bbox.x = newRelativeCoords.x; + selectedBox.bbox.y = newRelativeCoords.y; + } + } + } + else { + //If anchor side left or right only move in y direction + if (anchorSide === "right") { + gap = instance.classes.AuxUnitLayout.getCurrentRightGap(); + } + else { + gap = instance.classes.AuxUnitLayout.getCurrentLeftGap(); + } + + shift_y = drag_y - last_mouse_y; + box_new_y = selectedBox.bbox.y + shift_y; //Calculate new box position + + //Get absolute position + var absoluteCoords = instance.classes.AuxiliaryUnit.convertToAbsoluteCoord(selectedBox, selectedBox.bbox.x, box_new_y, cy); + var newRelativeCoords; + if (absoluteCoords.y - selectedBox.bbox.h/2 < (position.y - parentBbox.h/2) + gap) { //Box cannot go futher than parentBox + margin on left side + newRelativeCoords = instance.classes.AuxiliaryUnit.convertToRelativeCoord(selectedBox, absoluteCoords.x, + (position.y - parentBbox.h/2) + gap + selectedBox.bbox.h/2, cy); + selectedBox.bbox.y = newRelativeCoords.y; + } + else if (absoluteCoords.y + selectedBox.bbox.h/2 > (position.y + parentBbox.h/2) - gap) { //Box cannot go futher than parentBox - margin on right side + newRelativeCoords = instance.classes.AuxiliaryUnit.convertToRelativeCoord(selectedBox, absoluteCoords.x, + (position.y + parentBbox.h/2) - gap - selectedBox.bbox.h/2, cy); + selectedBox.bbox.y = newRelativeCoords.y; + } + else { //Else it is already relative + selectedBox.bbox.y = box_new_y; + } + + absoluteCoords = instance.classes.AuxiliaryUnit.convertToAbsoluteCoord(selectedBox, selectedBox.bbox.x, selectedBox.bbox.y, cy); + //Set anchor side changes + if (absoluteCoords.y === (position.y - parentBbox.h/2) + gap + selectedBox.bbox.h / 2) { //If it is on the top margin allow it to change anchor sides + //If it is in the top and mouse moves bottom it can go left anchor + if (last_mouse_x < drag_x && anchorSide === "left") { + selectedBox.anchorSide = "top"; //Set new anchor side + newRelativeCoords = instance.classes.AuxiliaryUnit.convertToRelativeCoord(selectedBox, (position.x - parentBbox.w/2) + + instance.classes.AuxUnitLayout.getCurrentTopGap(), (position.y - parentBbox.h/2), cy); + selectedBox.bbox.x = newRelativeCoords.x; + selectedBox.bbox.y = newRelativeCoords.y; + } + else if (last_mouse_x > drag_x && anchorSide === "right") { //If it is in the right and mouse moves up it can go top anchor side + selectedBox.anchorSide = "top"; //Set new anchor side + newRelativeCoords = instance.classes.AuxiliaryUnit.convertToRelativeCoord(selectedBox, (position.x + parentBbox.w/2) + - instance.classes.AuxUnitLayout.getCurrentTopGap(), (position.y - parentBbox.h/2), cy); + selectedBox.bbox.x = newRelativeCoords.x; + selectedBox.bbox.y = newRelativeCoords.y; + } + } + //If it on right it can pass right anchor side + else if (absoluteCoords.y === (position.y + parentBbox.h/2) - gap - selectedBox.bbox.h/2) { + if (last_mouse_x < drag_x && anchorSide === "left") { + selectedBox.anchorSide = "bottom"; //Set new anchor side + newRelativeCoords = instance.classes.AuxiliaryUnit.convertToRelativeCoord(selectedBox, (position.x - parentBbox.w/2) + + instance.classes.AuxUnitLayout.getCurrentBottomGap(), (position.y + parentBbox.h/2), cy); + selectedBox.bbox.x = newRelativeCoords.x; + selectedBox.bbox.y = newRelativeCoords.y; + } + else if (last_mouse_x > drag_x && anchorSide === "right") { //If it is in the bottom and mouse moves up it can go left anchor side + selectedBox.anchorSide = "bottom"; //Set new anchor side + newRelativeCoords = instance.classes.AuxiliaryUnit.convertToRelativeCoord(selectedBox, (position.x + parentBbox.w/2) + - instance.classes.AuxUnitLayout.getCurrentBottomGap(), (position.y + parentBbox.h/2), cy); + selectedBox.bbox.x = newRelativeCoords.x; + selectedBox.bbox.y = newRelativeCoords.y; + } + } + + } + + last_mouse_x = drag_x; + last_mouse_y = drag_y; + cy.style().update(); + }); + + cy.on("mouseup", function(event){ + appUtilities.disableInfoBoxRelocationDrag(); + if (selectedBox !== undefined && oldAnchorSide !== undefined) { + selectedBox.dashed = false; + instance.classes.AuxUnitLayout.modifyUnits(node, selectedBox, oldAnchorSide, cy); //Modify aux unit layouts + selectedBox = undefined; + anchorSide = undefined; + oldAnchorSide = undefined; + } + }); + + }); +} + +//Disables info-box relocation +appUtilities.disableInfoBoxRelocation = function(){ + var cy = this.getActiveCy(); + //Remove listerners + cy.off('mousedown', relocationHandler); + cy.off('mousemove', relocationDragHandler); + //Enable box selection + cy.autolock(false); //Make the nodes moveable again + cy.autounselectify(false); //Make the nodes selectable +} + +//Disables info-box dragging +appUtilities.disableInfoBoxRelocationDrag = function(){ + var cy = this.getActiveCy(); + //Remove listerners + cy.off('mousemove', relocationDragHandler); +} + module.exports = appUtilities; From f284f0cb8d03bb428f194cbfb1118dd92295220c Mon Sep 17 00:00:00 2001 From: leonarddrv Date: Tue, 12 Jun 2018 10:02:21 +0300 Subject: [PATCH 61/97] Neighborhood menu item moved #281 --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index e88c79018..bcabb153a 100644 --- a/index.html +++ b/index.html @@ -261,10 +261,10 @@ From 30a6d1528f97590480f21b101c99511b0e9f0a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20=C3=87and=C4=B1ro=C4=9Flu?= Date: Tue, 12 Jun 2018 11:22:01 +0300 Subject: [PATCH 62/97] Fix copy/paste bug #277 --- app/js/app-menu.js | 1 - 1 file changed, 1 deletion(-) diff --git a/app/js/app-menu.js b/app/js/app-menu.js index 6efc18810..8634e28d8 100644 --- a/app/js/app-menu.js +++ b/app/js/app-menu.js @@ -1097,7 +1097,6 @@ module.exports = function() { $(document).on('mouseup', function (e) { dragAndDropPlacement = false; appUtilities.removeDragImage(); - appUtilities.disableInfoBoxRelocationDrag(); }); $('#select-mode-icon').click(function (e) { From bd283f372700962621b31eb4ef0199a197b897d7 Mon Sep 17 00:00:00 2001 From: leonarddrv Date: Tue, 12 Jun 2018 12:53:47 +0300 Subject: [PATCH 63/97] Incorrect clone location bug is fixed #284 --- app/js/app-menu.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/js/app-menu.js b/app/js/app-menu.js index 8634e28d8..5338536d7 100644 --- a/app/js/app-menu.js +++ b/app/js/app-menu.js @@ -976,7 +976,9 @@ module.exports = function() { // use cy instance associated with chise instance var cy = chiseInstance.getCy(); - chiseInstance.cloneElements(cy.nodes(':selected')); + //When the menu option is clicked paste at mouse location is false + var pasteAtMouseLoc = false; + chiseInstance.cloneElements(cy.nodes(':selected'), pasteAtMouseLoc); }); /* From 6070e613439003a681766945686954aa5839de3c Mon Sep 17 00:00:00 2001 From: dorukcakmakci Date: Tue, 12 Jun 2018 14:34:11 +0300 Subject: [PATCH 64/97] Fix #263 The dropdown menu's are changed to be as wide as the text. Association: The delete icon for the first two input are disabled. The dropdown menu for output is removed. Dissociation: The dropdown menu for input is removed. --- app/css/chise.css | 11 ++++++++-- app/js/backbone-views.js | 23 +++++++++++++-------- index.html | 44 ++++++++++++++++++++++++---------------- 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/app/css/chise.css b/app/css/chise.css index 9e506f24f..b98d2601d 100644 --- a/app/css/chise.css +++ b/app/css/chise.css @@ -439,6 +439,14 @@ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { margin: 0; } +#template-modal-content { + position: fixed; + width: 600px; + top: 50%; + left: 50%; + margin-left: -300px; +} + .sbgn-input-small { width: 50px !important; } @@ -729,8 +737,7 @@ hr.inspector-divider { border-width: 1px !important; border-radius: calc !important; font-size: 12px; - padding-top: 0.5px; - padding-bottom: 0.5px; + align: center; } #sbgn-toolbar img { diff --git a/app/js/backbone-views.js b/app/js/backbone-views.js index 142c9deee..175b2d5b1 100644 --- a/app/js/backbone-views.js +++ b/app/js/backbone-views.js @@ -1829,21 +1829,21 @@ var ReactionTemplateView = Backbone.View.extend({ + i + "' value=''>" + ""; - html += ""; + html += ""; $('#template-reaction-dissociated-table :input.template-reaction-textbox').last().closest('tr').after(html); } else if( type == "left"){ - html += "" + "" + ""; - html += ""; + html += ""; $('#template-reversible-input-table :input.template-reaction-textbox').last().closest('tr').after(html); } else{ - html += "" + "" + ""; html += ""; @@ -1883,7 +1883,10 @@ var ReactionTemplateView = Backbone.View.extend({ var templateType = $('#reaction-template-type-select').val(); var templateReactionComplexName = $('#template-reaction-complex-name').val(); var nodeNames = $('#template-reaction-dissociated-table :input.template-reaction-textbox').map(function(){ - return $(this).val(); + return { + name: $(this).val(), + id: $(this).attr('name').charAt(0) + }; }).toArray(); var nodeTypes = $('#template-reaction-dissociated-table :input.template-reaction-molecule-type :selected').map(function(){ return $(this).val(); @@ -1892,8 +1895,9 @@ var ReactionTemplateView = Backbone.View.extend({ for( var i = 0; i < nodeNames.length; i++){ nodeList.push( { - "name": nodeNames[i], - "type": nodeTypes[i] + "name": nodeNames[i].name, + "type": nodeTypes[i], + "id": nodeNames[i].id } ); } @@ -1973,6 +1977,7 @@ var ReactionTemplateView = Backbone.View.extend({ var self = this; self.template = _.template($("#reaction-template-template").html()); + $(document).on('change', '#reaction-template-type-select', function (e) { var valueSelected = $(this).val(); self.switchInputOutput(valueSelected); @@ -2076,7 +2081,7 @@ var ReactionTemplateView = Backbone.View.extend({ var self = this; self.template = _.template($("#reaction-template-template").html()); $(self.el).html(self.template); - self.disableDeleteButtonStyle(); + self.disableDeleteButtonStyle("reaction"); $(self.el).modal('show'); self.associatedHTMLContent = $('#reaction-template-left-td').html(); diff --git a/index.html b/index.html index bcabb153a..b0fd36e4d 100644 --- a/index.html +++ b/index.html @@ -1053,7 +1053,7 @@
+ Find all paths of specified length limit from a set of source entities to a set of target entities
- Length limit can be at most 3. + Length limit can be at most 3.
"; if( type == "reaction"){ - html += "" + "" + "
- +
@@ -1740,7 +1740,7 @@