diff --git a/Gemfile~ b/Gemfile~ index 1f7c3bd8..6b2f6e48 100644 --- a/Gemfile~ +++ b/Gemfile~ @@ -14,7 +14,7 @@ gem 'json' gem 'rails3-jquery-autocomplete' gem 'best_in_place' #gem 'therubyracer' #optional -#gem 'rb-readline' +gem 'rb-readline' # Gems used only for assets and not required # in production environments by default. diff --git a/README.rdoc b/README.rdoc index 9ed21fa0..9f2c9edd 100644 --- a/README.rdoc +++ b/README.rdoc @@ -1,4 +1,4 @@ -How to code in Metamaps +==How to code in Metamaps Here are the important folders/files: @@ -17,7 +17,7 @@ app/assets/views/*.js.erb: Javascript that is called in response to, e.g., editi Setting up the database: 1) Copy database.yml.default to database.yml - - Then you'll need to figure out how to configure it to work with Postgresql (which you need to install - try Herokuapp's exe or app) + - Then you'll need to figure out how to configure it to work with Postgresql (which you need to install - try Herokuapp's exe or app) 2) In a terminal: $ rake db:create $ rake db:migrate @@ -25,8 +25,9 @@ Setting up the database: Running the server: -$rails s #runs the server -$rails c #gives you an interactive console + $rails s #runs the server + $ + $rails c #gives you an interactive console ==Installing on Ubuntu diff --git a/app/assets/javascripts/Jit/graphsettings-event-handlers.js b/app/assets/javascripts/Jit/graphsettings-event-handlers.js index f18d6085..d31e7641 100644 --- a/app/assets/javascripts/Jit/graphsettings-event-handlers.js +++ b/app/assets/javascripts/Jit/graphsettings-event-handlers.js @@ -1,5 +1,4 @@ function selectEdgeOnClickHandler(adj, e) { - if (Mconsole.busy) return; //editing overrides everything else @@ -29,6 +28,29 @@ function selectEdgeOnClickHandler(adj, e) { }//selectEdgeOnClickHandler function nodeDoubleClickHandler(node, e) { + keepFromCommons(node); +} + +function enterKeyHandler() { + var selectedNodesCopy = MetamapsModel.selectedNodes.slice(0); + var len = selectedNodesCopy.length; + for (var i = 0; i < len; i += 1) { + n = selectedNodesCopy[i]; + keepFromCommons(n); + }//for + Mconsole.plot(); +}//enterKeyHandler + +function escKeyHandler() { + deselectAllEdges(); + deselectAllNodes(); +}//escKeyHandler + +/* + * Make a node "in the commons" (with a green circle) lose its + * green circle so it stays on the console/map/... + */ +function keepFromCommons(node) { if (userid == null) { return; } @@ -58,7 +80,6 @@ function nodeDoubleClickHandler(node, e) { node.setData('mappingid', data.id); }); } - }//doubleClickNodeHandler /* @@ -167,7 +188,11 @@ function onDragMoveTopicHandler(node, eventInfo, e) { if ( e.touches || (e.button == 0 && !e.altKey && (e.buttons == 0 || e.buttons == 1 || e.buttons == undefined))) { //if the node dragged isn't already selected, select it var whatToDo = handleSelectionBeforeDragging(node, e); - if (whatToDo == 'only-drag-this-one') { + if (node.pos.rho || node.pos.rho === 0) { + var rho = Math.sqrt(pos.x * pos.x + pos.y * pos.y); + var theta = Math.atan2(pos.y, pos.x); + node.pos.setp(theta, rho); + } else if (whatToDo == 'only-drag-this-one') { node.pos.setc(pos.x, pos.y); node.setData('xloc', pos.x); node.setData('yloc', pos.y); @@ -178,16 +203,18 @@ function onDragMoveTopicHandler(node, eventInfo, e) { var xOffset = new Array(); var yOffset = new Array(); for (var i = 0; i < len; i += 1) { - n = MetamapsModel.selectedNodes[i]; - xOffset[i] = n.getData('xloc') - node.getData('xloc'); - yOffset[i] = n.getData('yloc') - node.getData('yloc'); + var n = MetamapsModel.selectedNodes[i]; + xOffset[i] = n.pos.x - node.pos.x; + yOffset[i] = n.pos.y - node.pos.y; }//for for (var i = 0; i < len; i += 1) { - n = MetamapsModel.selectedNodes[i]; - n.pos.setc(pos.x + xOffset[i], pos.y + yOffset[i]); - n.setData('xloc', pos.x + xOffset[i]); - n.setData('yloc', pos.y + yOffset[i]); + var n = MetamapsModel.selectedNodes[i]; + var x = pos.x + xOffset[i]; + var y = pos.y + yOffset[i]; + n.pos.setc(x, y); + n.setData('xloc', x); + n.setData('yloc', y); }//for }//if diff --git a/app/assets/javascripts/Jit/graphsettings-model.js b/app/assets/javascripts/Jit/graphsettings-model.js index dbfecf4f..e5372c9e 100644 --- a/app/assets/javascripts/Jit/graphsettings-model.js +++ b/app/assets/javascripts/Jit/graphsettings-model.js @@ -20,6 +20,10 @@ MetamapsModel.widthOfLabel = null; //is the mouse hovering over an edge? which one? MetamapsModel.edgeHoveringOver = false; +//coordinates of shift click for using box select +MetamapsModel.boxStartCoordinates = false; +MetamapsModel.boxEndCoordinates = false; + //double clicking of nodes or canvas MetamapsModel.lastNodeClick = 0; MetamapsModel.lastCanvasClick = 0; diff --git a/app/assets/javascripts/Jit/graphsettings.js b/app/assets/javascripts/Jit/graphsettings.js index b9002d79..d7a4b2d1 100644 --- a/app/assets/javascripts/Jit/graphsettings.js +++ b/app/assets/javascripts/Jit/graphsettings.js @@ -105,7 +105,11 @@ function graphSettings(type, embed) { if (e.target.id != "infovis-canvas") return false; //topic and synapse editing cards - if (!Mconsole.events.moved) hideCards(); + if (!Mconsole.events.moved && !node) { + hideCards(); + deselectAllNodes(); + deselectAllEdges(); + } //clicking on a node, or clicking on blank part of canvas? if (node.nodeFrom) { @@ -427,10 +431,65 @@ var nodeSettings = { } } +function drawSelectBox(eventInfo, e) { + var ctx=Mconsole.canvas.getCtx(); + + var startX = MetamapsModel.boxStartCoordinates.x, + startY = MetamapsModel.boxStartCoordinates.y, + currX = eventInfo.getPos().x, + currY = eventInfo.getPos().y; + + Mconsole.plot(); + ctx.moveTo(startX,startY); + ctx.lineTo(startX,currY); + ctx.stroke(); + ctx.lineTo(currX,currY); + ctx.stroke(); + ctx.lineTo(currX,startY); + ctx.stroke(); + ctx.lineTo(startX,startY); + ctx.stroke(); +} + +function selectNodesWithBox() { + + var sX = MetamapsModel.boxStartCoordinates.x, + sY = MetamapsModel.boxStartCoordinates.y, + eX = MetamapsModel.boxEndCoordinates.x, + eY = MetamapsModel.boxEndCoordinates.y; + + + Mconsole.graph.eachNode(function (n) { + var x = n.pos.x, y = n.pos.y; + + if ((sX < x && x < eX && sY < y && y < eY) || (sX > x && x > eX && sY > y && y > eY) || (sX > x && x > eX && sY < y && y < eY) || (sX < x && x < eX && sY > y && y > eY)) { + selectNode(n); + } + }); + + MetamapsModel.boxStartCoordinates = false; + MetamapsModel.boxEndCoordinates = false; + Mconsole.plot(); +} function onMouseMoveHandler(node, eventInfo, e) { if (Mconsole.busy) return; + + if (!MetamapsModel.boxStartCoordinates && e.shiftKey) { + MetamapsModel.boxStartCoordinates = eventInfo.getPos(); + return; + } + if (MetamapsModel.boxStartCoordinates && e.shiftKey) { + drawSelectBox(eventInfo,e); + return; + } + if (MetamapsModel.boxStartCoordinates && !e.shiftKey) { + MetamapsModel.boxEndCoordinates = eventInfo.getPos(); + Mconsole.plot(); + selectNodesWithBox(); + return; + } var node = eventInfo.getNode(); var edge = eventInfo.getEdge(); diff --git a/app/assets/javascripts/Jit/select-edit-delete-nodes-and-edges.js b/app/assets/javascripts/Jit/select-edit-delete-nodes-and-edges.js index fa5ee66c..c328839d 100644 --- a/app/assets/javascripts/Jit/select-edit-delete-nodes-and-edges.js +++ b/app/assets/javascripts/Jit/select-edit-delete-nodes-and-edges.js @@ -75,6 +75,16 @@ function add_perms_form(edge) { $('#edit_synapse .click-to-edit').attr('title', 'Click to Edit'); $('#edit_synapse .click-to-edit').append(best_in_place_perms(edge)); $('#edit_synapse .editSettings').append('
'); + + $('#edit_synapse').find('.best_in_place_permission').bind("ajax:success", function() { + var permission = $(this).html(); + switch(permission) { + case 'commons': $('#edit_synapse .mapPerm').html('co'); break; + case 'public': $('#edit_synapse .mapPerm').html('pu'); break; + case 'private': $('#edit_synapse .mapPerm').html('pr'); break; + }//switch + }); + $('#edit_synapse .permActivator').bind('mouseover', function() { clearTimeout(MetamapsModel.edgePermTimer2); that = this; @@ -220,12 +230,21 @@ function best_in_place_perms(edge) { }//best_in_place_perms function deselectAllEdges() { - for (var i = 0; i < MetamapsModel.selectedEdges.length; i += 1) { + var l = MetamapsModel.selectedEdges.length; + for (var i = l-1; i >= 0; i -= 1) { var edge = MetamapsModel.selectedEdges[i]; deselectEdge(edge); } } +function deselectAllNodes() { + var l = MetamapsModel.selectedNodes.length; + for (var i = l-1; i >= 0; i -= 1) { + var node = MetamapsModel.selectedNodes[i]; + deselectNode(node); + } +} + // this is for hiding one topic from your canvas function removeEdge(edge) { var id = edge.getData("id"); @@ -251,7 +270,8 @@ function hideEdge(edge) { } function hideSelectedEdges() { - for (var i = 0; i < MetamapsModel.selectedEdges.length; i += 1) { + var l = MetamapsModel.selectedEdges.length; + for (var i = l-1; i >= 0; i -= 1) { var edge = MetamapsModel.selectedEdges[i]; hideEdge(edge); } @@ -259,7 +279,8 @@ function hideSelectedEdges() { } function removeSelectedEdges() { - for (var i = 0; i < MetamapsModel.selectedEdges.length; i += 1) { + var l = MetamapsModel.selectedEdges.length; + for (var i = l-1; i >= 0; i -= 1) { if (mapid != null) { var edge = MetamapsModel.selectedEdges[i]; var id = edge.getData("id"); @@ -275,7 +296,8 @@ function removeSelectedEdges() { } function deleteSelectedEdges() { - for (var i = 0; i < MetamapsModel.selectedEdges.length; i += 1) { + var l = MetamapsModel.selectedEdges.length; + for (var i = l-1; i >= 0; i -= 1) { var edge = MetamapsModel.selectedEdges[i]; var id = edge.getData("id"); $.ajax({ @@ -390,11 +412,11 @@ function hideNode(nodeid) { } function hideSelectedNodes() { - Mconsole.graph.eachNode( function (n) { - if (n.getData('whiteCircle') == true) { - hideNode(n.id); - } - }); + var l = MetamapsModel.selectedNodes.length; + for (var i = l-1; i >= 0; i -= 1) { + var node = MetamapsModel.selectedNodes[i]; + hideNode(node.id); + } } function removeNode(nodeid) { @@ -409,11 +431,11 @@ function removeNode(nodeid) { } function removeSelectedNodes() { if (mapperm) { - Mconsole.graph.eachNode( function (n) { - if (n.getData('whiteCircle') == true) { - removeNode(n.id); - } - }); + var l = MetamapsModel.selectedNodes.length; + for (var i = l-1; i >= 0; i -= 1) { + var node = MetamapsModel.selectedNodes[i]; + removeNode(node.id); + } } } @@ -428,9 +450,9 @@ function deleteNode(nodeid) { }); } function deleteSelectedNodes() { - Mconsole.graph.eachNode( function (n) { - if (n.getData('whiteCircle') == true) { - deleteNode(n.id); - } - }); + var l = MetamapsModel.selectedNodes.length; + for (var i = l-1; i >= 0; i -= 1) { + var node = MetamapsModel.selectedNodes[i]; + deleteNode(node.id); + } } diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 86984539..47bba8d2 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -300,3 +300,11 @@ function MconsoleReset() { Mconsole.canvas.scale((1/mX),(1/mY)); } + +$('*').keypress(function(e) { + switch(e.which) { + case 13: enterKeyHandler(); break; + case 27: escKeyHandler(); break; + default: //alert(e.which); break; + } +}); diff --git a/app/views/main/console.html.erb b/app/views/main/console.html.erb index 93abd496..83f96661 100644 --- a/app/views/main/console.html.erb +++ b/app/views/main/console.html.erb @@ -7,6 +7,7 @@ #%>
+ <% if authenticated? %> diff --git a/app/views/maps/show.html.erb b/app/views/maps/show.html.erb index 662664ec..1f40a4ff 100644 --- a/app/views/maps/show.html.erb +++ b/app/views/maps/show.html.erb @@ -9,6 +9,7 @@ <% end %> + <% if authenticated? %> <% if (@map.permission == "commons" && authenticated?) || @map.user == user %> diff --git a/app/views/topics/show.html.erb b/app/views/topics/show.html.erb index 552e2819..10fcf216 100644 --- a/app/views/topics/show.html.erb +++ b/app/views/topics/show.html.erb @@ -15,6 +15,7 @@ #%>
+ <% if authenticated? %> <% end %>