From 2abeb73e9af1da6f8fe831005a6a40df107e3596 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Sat, 1 Mar 2014 19:02:27 -0800 Subject: [PATCH] styled synapse card --- app/assets/javascripts/Jit/graphsettings.js | 53 ++++++---- app/assets/javascripts/Jit/jit2.0.0.js | 23 ++-- .../Jit/select-edit-delete-nodes-and-edges.js | 100 ++++++++---------- app/assets/javascripts/application.js | 18 ++++ app/assets/stylesheets/base.css | 81 +++++++++++++- app/views/users/sessions/new.html.erb | 1 + 6 files changed, 183 insertions(+), 93 deletions(-) diff --git a/app/assets/javascripts/Jit/graphsettings.js b/app/assets/javascripts/Jit/graphsettings.js index a6554380..316608b1 100644 --- a/app/assets/javascripts/Jit/graphsettings.js +++ b/app/assets/javascripts/Jit/graphsettings.js @@ -334,30 +334,47 @@ var nodeSettings = { //now adjust the label placement var ctx = canvas.getCtx(); - var radius = canvas.getSize(); - var x = parseInt((pos.x + posChild.x - (desc.length * 5)) /2); - var y = parseInt((pos.y + posChild.y) /2); - ctx.font = 'bold 14px arial'; + ctx.font = '14px arial'; + ctx.fillStyle = '#222222'; + ctx.textBaseline = 'hanging'; + + // helper function to determine how many lines are needed + // Line Splitter Function + // copyright Stephen Chapman, 19th April 2006 + // you may copy this code but please keep the copyright notice as well + function splitLine(st,n) {var b = ''; var s = st;while (s.length > n) {var c = s.substring(0,n);var d = c.lastIndexOf(' ');var e =c.lastIndexOf('\n');if (e != -1) d = e; if (d == -1) d = n; b += c.substring(0,d) + '\n';s = s.substring(d+1);}return b+s;} + var arrayOfLabelLines = splitLine(desc,30).split('\n'); + var index, lineWidths = []; + for (index = 0; index < arrayOfLabelLines.length; ++index) { + lineWidths.push( ctx.measureText( arrayOfLabelLines[index] ).width ) + } + var width = Math.max.apply(null, lineWidths) + 8; + var height = (16 * arrayOfLabelLines.length) + 8; + + var x = (pos.x + posChild.x - width)/2; + var y = ((pos.y + posChild.y) /2) - height/2; + var radius = 5; //render background - ctx.fillStyle = '#FFF'; - var margin = 5; - var height = 14 + margin; //font size + margin - var CURVE = height / 2; //offset for curvy corners - var width = ctx.measureText(desc).width + 2 * margin - 2 * CURVE - var labelX = x - margin + CURVE; - var labelY = y - height + margin; - ctx.fillRect(labelX, labelY, width, height); - - //curvy corners woo - circles in place of last CURVE pixels of rect ctx.beginPath(); - ctx.arc(labelX, labelY + CURVE, CURVE, 0, 2 * Math.PI, false); - ctx.arc(labelX + width, labelY + CURVE, CURVE, 0, 2 * Math.PI, false); + ctx.moveTo(x + radius, y); + ctx.lineTo(x + width - radius, y); + ctx.quadraticCurveTo(x + width, y, x + width, y + radius); + ctx.lineTo(x + width, y + height - radius); + ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); + ctx.lineTo(x + radius, y + height); + ctx.quadraticCurveTo(x, y + height, x, y + height - radius); + ctx.lineTo(x, y + radius); + ctx.quadraticCurveTo(x, y, x + radius, y); + ctx.closePath(); ctx.fill(); //render text - ctx.fillStyle = '#000'; - ctx.fillText(desc, x, y); + ctx.fillStyle = '#FFF'; + ctx.textAlign = 'center'; + for (index = 0; index < arrayOfLabelLines.length; ++index) { + ctx.fillText(arrayOfLabelLines[index], x + (width/2), y + 5 + (16*index)); + } } }, 'contains' : function(adj, pos) { var from = adj.nodeFrom.pos.getc(true), diff --git a/app/assets/javascripts/Jit/jit2.0.0.js b/app/assets/javascripts/Jit/jit2.0.0.js index 85c010ff..771c5489 100644 --- a/app/assets/javascripts/Jit/jit2.0.0.js +++ b/app/assets/javascripts/Jit/jit2.0.0.js @@ -7238,8 +7238,9 @@ Graph.Label.Native = new Class({ function splitLine(st,n) {var b = ''; var s = st;while (s.length > n) {var c = s.substring(0,n);var d = c.lastIndexOf(' ');var e =c.lastIndexOf('\n');if (e != -1) d = e; if (d == -1) d = n; b += c.substring(0,d) + '\n';s = s.substring(d+1);}return b+s;} var arrayOfLabelLines = splitLine(node.name,30).split('\n'); //render background - ctx.fillStyle = 'rgba(24,32,46, 0.8)'; - ctx.strokeStyle = 'rgba(24,32,46, 1)'; + ctx.fillStyle = 'rgba(24,32,46, 1)'; + ctx.strokeStyle = node.getData('whiteCircle') ? '#FFF' : 'rgba(24,32,46, 1)'; + ctx.lineWidth = 2; var height = 25 * arrayOfLabelLines.length; //font size + margin var index, lineWidths = []; @@ -7262,13 +7263,14 @@ Graph.Label.Native = new Class({ ctx.lineTo(x, y + radius); ctx.quadraticCurveTo(x, y, x + radius, y); ctx.closePath(); - ctx.stroke(); ctx.fill(); + ctx.stroke(); ctx.fillStyle = ctx.strokeStyle = node.getLabelData('color'); - // END METAMAPS CODE - this.renderLabel(canvas, node, controller); + this.renderLabel(arrayOfLabelLines, canvas, node, controller); + // END METAMAPS CODE + // ORIGINAL CODE this.renderLabel(canvas, node, controller); }, /* @@ -7284,19 +7286,14 @@ Graph.Label.Native = new Class({ node - A . controller - A configuration object. See also , , . */ - renderLabel: function(canvas, node, controller) { + renderLabel: function(customLabel, canvas, node, controller) { var ctx = canvas.getCtx(); var pos = node.pos.getc(true); //ctx.fillText(node.name, pos.x, pos.y + node.getData("height") / 2); // START METAMAPS CODE - // Line Splitter Function - // copyright Stephen Chapman, 19th April 2006 - // you may copy this code but please keep the copyright notice as well - function splitLine(st,n) {var b = ''; var s = st;while (s.length > n) {var c = s.substring(0,n);var d = c.lastIndexOf(' ');var e =c.lastIndexOf('\n');if (e != -1) d = e; if (d == -1) d = n; b += c.substring(0,d) + '\n';s = s.substring(d+1);}return b+s;} - var arrayOfLabelLines = splitLine(node.name,30).split('\n'); var index; - for (index = 0; index < arrayOfLabelLines.length; ++index) { - ctx.fillText(arrayOfLabelLines[index], pos.x, pos.y + node.getData("height") + 5 + (25*index)); + for (index = 0; index < customLabel.length; ++index) { + ctx.fillText(customLabel[index], pos.x, pos.y + node.getData("height") + 5 + (25*index)); } // END METAMAPS CODE }, 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 311d3371..69d246c3 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 @@ -16,7 +16,6 @@ function centerOn(nodeid) { } function editEdge(edge, e) { - if (authorizeToEdit(edge)) { //reset so we don't interfere with other edges, but first, save its x and y var myX = $('#edit_synapse').css('left'); var myY = $('#edit_synapse').css('top'); @@ -29,7 +28,12 @@ function editEdge(edge, e) { //classes to make best_in_place happy var edit_div = document.createElement('div'); edit_div.setAttribute('id', 'edit_synapse'); - edit_div.className = 'permission canEdit'; + if (authorizeToEdit(edge)) { + edit_div.className = 'permission canEdit'; + edit_div.className += edge.getData('userid') === userid ? ' yourEdge' : ''; + } else { + edit_div.className = 'permission cannotEdit'; + } $('.main .wrapper').append(edit_div); populateEditEdgeForm(edge); @@ -49,16 +53,15 @@ function editEdge(edge, e) { $('#edit_synapse').show(); MetamapsModel.edgecardInUse = edge.data.$id; - } - else if ((! authorizeToEdit(edge)) && userid) { - alert("You don't have the permissions to edit this synapse."); - } } function populateEditEdgeForm(edge) { - add_perms_form(edge); - add_direction_form(edge); add_name_form(edge); + add_user_info(edge); + add_perms_form(edge); + if (authorizeToEdit(edge)) { + add_direction_form(edge); + } } function add_name_form(edge) { @@ -68,7 +71,7 @@ function add_name_form(edge) { $('#edit_synapse_name').attr('class', 'best_in_place best_in_place_desc'); $('#edit_synapse_name').attr('data-object', 'synapse'); $('#edit_synapse_name').attr('data-attribute', 'desc'); - $('#edit_synapse_name').attr('data-type', 'input'); + $('#edit_synapse_name').attr('data-type', 'textarea'); $('#edit_synapse_name').attr('data-nil', data_nil); $('#edit_synapse_name').attr('data-url', '/synapses/' + edge.getData("id")); $('#edit_synapse_name').html(edge.getData("desc")); @@ -90,59 +93,40 @@ function add_name_form(edge) { }); } +function add_user_info(edge) { + $('#edit_synapse').append('
Created by ' + edge.getData("username") + '
'); +} + function add_perms_form(edge) { //permissions - if owner, also allow permission editing - $('#edit_synapse').append('
'); - $('#edit_synapse .mapPerm').html(mk_permission(edge)); + $('#edit_synapse').append('
'); + + // ability to change permission + var selectingPermission = false; if (userid == edge.getData('userid')) { - $('#edit_synapse').append('
'); - $('#edit_synapse .permActivator').append('
'); - $('#edit_synapse .editSettings').append('Permissions:'); - $('#edit_synapse .editSettings').append(''); - $('#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; - MetamapsModel.edgePermTimer1 = setTimeout(function() { - if (! MetamapsModel.edgePermSliding) { - MetamapsModel.edgePermSliding = true; - $(that).animate({ - width: '203px', - height: '37px' - }, 300, function() { - MetamapsModel.edgePermSliding = false; - }); - } - }, 300); - }); - $('#edit_synapse .permActivator').bind('mouseout', function () { - clearTimeout(MetamapsModel.edgePermTimer1); - that = this; - MetamapsModel.edgePermTimer2 = setTimeout(function() { - if (! MetamapsModel.edgePermSliding) { - MetamapsModel.edgePermSliding = true; - $(that).animate({ - height: '16px', - width: '16px' - }, 300, function() { - MetamapsModel.edgePermSliding = false; - }); - } - },800); + $('#edit_synapse.yourEdge .mapPerm').click(function() { + if (!selectingPermission) { + selectingPermission = true; + $(this).addClass('minimize'); // this line flips the drop down arrow to a pull up arrow + if ( $(this).hasClass('co') ) { + $(this).append('
'); + } else if ( $(this).hasClass('pu') ) { + $(this).append('
'); + } else if ( $(this).hasClass('pr') ) { + $(this).append('
'); } - ); + $('#edit_synapse .permissionSelect li').click(function(event) { + selectingPermission = false; + var permission = $(this).attr('class'); + updateSynapsePermission(edge, permission); + event.stopPropagation(); + }); + } else { + selectingPermission = false; + $(this).removeClass('minimize'); // this line flips the pull up arrow to a drop down arrow + $('#edit_synapse .permissionSelect').remove(); + } + }); } }//add_perms_form diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 26bdb918..4f779239 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -718,6 +718,24 @@ function updateTopicPermission(node, permission) { }); } +function updateSynapsePermission(edge, permission) { + var mdata = { "synapse": { "permission": permission } }; + $.ajax({ + type: "PUT", + dataType: 'json', + url: "/synapses/" + edge.data.$id, + data: mdata, + success: function(data) { + $('#edit_synapse .mapPerm').removeClass('co pu pr minimize').addClass( permission.substring(0,2) ); + $('#edit_synapse .permissionSelect').remove(); + edge.setData("permission", permission); + }, + error: function(){ + alert('failed to update permission'); + } + }); +} + function MconsoleReset() { var tX = Mconsole.canvas.translateOffsetX; diff --git a/app/assets/stylesheets/base.css b/app/assets/stylesheets/base.css index fa4b11b5..2e32ceb3 100644 --- a/app/assets/stylesheets/base.css +++ b/app/assets/stylesheets/base.css @@ -468,11 +468,23 @@ font-family: 'LatoLight'; position: static; display: inline-block; color: #000; - margin: 2px; } #edit_synapse .mapPerm { - margin-left: 1em; + width: 20px; + height:20px; + background-repeat: no-repeat; + background-size: 20px 20px; + margin: 10px 12px 0 12px; +} +#edit_synapse .mapPerm.co { + background-image: url("/assets/MMCCicon_commons.png"); +} +#edit_synapse .mapPerm.pu { + background-image: url("/assets/MMCCicon_public.png"); +} +#edit_synapse .mapPerm.pr { + background-image: url("/assets/MMCCicon_private.png"); } #edit_synapse .permActivator { @@ -481,20 +493,81 @@ font-family: 'LatoLight'; } #edit_synapse { - background: white; + background: url("/assets/MMCCicon_synapse_black.png") no-repeat scroll 0 center / 30px 30px #FFFFFF; border-radius: 5px; - padding: 5px; + padding: 5px 5px 5px 30px; color: #000; } #edit_synapse_name { margin-left: 0.4em; + border-bottom: 1px solid black; + text-align:center; + max-width: 160px; +} + +#edgeUser { + display:inline-block; + background-position: center center; + background-repeat: no-repeat; + background-size: 20px 20px; + height: 20px; + min-width: 20px; + position: relative; + background-image: url("MMCCicon_mapper_black.png"); + margin: 10px 0 0 10px; +} +#edgeUser.hoverForTip:hover .tip { + display:block; +} +#edgeUser .tip { + background: none repeat scroll 0 0 #000000; + border-radius: 4px; + color: #FFFFFF; + display: none; + font-family: 'LatoRegular'; + font-size: 15px !important; + line-height: 17px; + padding: 3px 5px 2px; + position: absolute; + left: 0; + text-align: center; + top: 23px; + z-index: 100; } #edit_synapse .click-to-edit { margin-left: 0.3em; } +#edit_synapse.yourEdge .mapPerm:hover { + background-image: url(/assets/MMCCicon_maximize_arrow_black.png); + background-size: 24px 17px; + background-position: 0px 2px; + cursor:pointer; +} +#edit_synapse.yourEdge .mapPerm.minimize { + background-image: url(MMCCicon_minimize_arrow_black.png) !important; + background-size: 24px 17px; + background-position: 0px 2px; + cursor: pointer; +} +#edit_synapse .mapPerm .permissionSelect { + list-style: none; + width: 26px; + height: 52px; + position: relative; + top: 20px; + left:-3px; +} +#edit_synapse .mapPerm .permissionSelect li { + width: 26px; + height: 26px; + background-repeat: no-repeat; + background-position: center center; + background-size: 20px 20px; + background-color:white; +} /* Map Cards */ diff --git a/app/views/users/sessions/new.html.erb b/app/views/users/sessions/new.html.erb index df778627..d821f1ec 100644 --- a/app/views/users/sessions/new.html.erb +++ b/app/views/users/sessions/new.html.erb @@ -15,6 +15,7 @@
<%= f.submit "Sign in" %>
+
<%- if devise_mapping.recoverable? && controller_name != 'passwords' %> <%= link_to "Forgot your password?", new_password_path(resource_name) %>
<% end -%>