diff --git a/Gemfile.lock b/Gemfile.lock index ed4f0c01..cc33f0b6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -60,7 +60,6 @@ GEM railties (>= 3.1.0, < 5.0) thor (~> 0.14) json (1.7.6) - libv8 (3.11.8.13) mail (2.4.4) i18n (>= 0.4.0) mime-types (~> 1.16) @@ -95,10 +94,8 @@ GEM rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) rake (10.0.3) - rb-readline (0.4.2) rdoc (3.12) json (~> 1.4) - ref (1.0.2) sass (3.2.1) sass-rails (3.2.5) railties (~> 3.2.0) @@ -109,9 +106,6 @@ GEM multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - therubyracer (0.11.4) - libv8 (~> 3.11.8.12) - ref thor (0.16.0) tilt (1.3.3) treetop (1.4.12) @@ -139,7 +133,5 @@ DEPENDENCIES pg rails (= 3.2.11) rails3-jquery-autocomplete - rb-readline sass-rails (~> 3.2.3) - therubyracer uglifier (>= 1.0.3) diff --git a/Gemfile~ b/Gemfile~ new file mode 100644 index 00000000..1f7c3bd8 --- /dev/null +++ b/Gemfile~ @@ -0,0 +1,46 @@ +source 'https://rubygems.org' + +gem 'rails', '3.2.11' + +# Bundle edge Rails instead: +# gem 'rails', :git => 'git://github.com/rails/rails.git' + +gem 'pg' +gem 'authlogic' +gem 'cancan' +gem 'formula' +gem 'formtastic' +gem 'json' +gem 'rails3-jquery-autocomplete' +gem 'best_in_place' +#gem 'therubyracer' #optional +#gem 'rb-readline' + +# Gems used only for assets and not required +# in production environments by default. +group :assets do + gem 'sass-rails', '~> 3.2.3' + gem 'coffee-rails', '~> 3.2.1' + + # See https://github.com/sstephenson/execjs#readme for more supported runtimes + # gem 'therubyracer' + + gem 'uglifier', '>= 1.0.3' +end + +gem 'jquery-rails', '2.1.2' + +# To use ActiveModel has_secure_password +# gem 'bcrypt-ruby', '~> 3.0.0' + +# To use Jbuilder templates for JSON + gem 'jbuilder' + +# Use unicorn as the web server +# gem 'unicorn' + +# Deploy with Capistrano +# gem 'capistrano' + +# To use debugger +# gem 'ruby-debug19', :require => 'ruby-debug' diff --git a/app/assets/javascripts/Jit/graphsettings-event-handlers.js b/app/assets/javascripts/Jit/graphsettings-event-handlers.js index 759b187c..30622f35 100644 --- a/app/assets/javascripts/Jit/graphsettings-event-handlers.js +++ b/app/assets/javascripts/Jit/graphsettings-event-handlers.js @@ -177,8 +177,8 @@ function onDragMoveTopicHandler(node, eventInfo, e) { $('#new_synapse').fadeOut('fast'); $('#new_topic').fadeOut('fast'); var pos = eventInfo.getPos(); - // if it's a left click, move the node - if (e.button == 0 && !e.altKey && (e.buttons == 0 || e.buttons == 1 || e.buttons == undefined)) { + // if it's a left click, or a touch, move the node + 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') { @@ -252,3 +252,63 @@ function onDragMoveTopicHandler(node, eventInfo, e) { } } } + +var lastDist = 0; + +function getDistance(p1, p2) { + return Math.sqrt(Math.pow((p2.x - p1.x), 2) + Math.pow((p2.y - p1.y), 2)); +} + +function touchPanZoomHandler(eventInfo, e) { + if (e.touches.length == 1) { + var thispos = touchPos, + currentPos = eventInfo.getPos(), + canvas = Mconsole.canvas, + ox = canvas.translateOffsetX, + oy = canvas.translateOffsetY, + sx = canvas.scaleOffsetX, + sy = canvas.scaleOffsetY; + currentPos.x *= sx; + currentPos.y *= sy; + currentPos.x += ox; + currentPos.y += oy; + //var x = currentPos.x - thispos.x, + // y = currentPos.y - thispos.y; + var x = currentPos.x - thispos.x, + y = currentPos.y - thispos.y; + touchPos = currentPos; + Mconsole.canvas.translate(x * 1/sx, y * 1/sy); + } + else if (e.touches.length == 2) { + var touch1 = e.touches[0]; + var touch2 = e.touches[1]; + + var dist = getDistance({ + x: touch1.clientX, + y: touch1.clientY + }, { + x: touch2.clientX, + y: touch2.clientY + }); + + if(!lastDist) { + lastDist = dist; + } + + var scale = dist / lastDist; + + console.log(scale); + + if (8 >= Mconsole.canvas.scaleOffsetX*scale && Mconsole.canvas.scaleOffsetX*scale >= 1) { + Mconsole.canvas.scale(scale, scale); + } + if (Mconsole.canvas.scaleOffsetX < 0.5) { + Mconsole.canvas.viz.labels.hideLabels(true); + } + else if (Mconsole.canvas.scaleOffsetX > 0.5) { + Mconsole.canvas.viz.labels.hideLabels(false); + } + lastDist = dist; + } + +} diff --git a/app/assets/javascripts/Jit/graphsettings-model.js b/app/assets/javascripts/Jit/graphsettings-model.js index d9cd00c1..dbfecf4f 100644 --- a/app/assets/javascripts/Jit/graphsettings-model.js +++ b/app/assets/javascripts/Jit/graphsettings-model.js @@ -15,6 +15,7 @@ MetamapsModel.selectedNodes = new Array(); //is any showcard open right now? which one? MetamapsModel.showcardInUse = null; +MetamapsModel.widthOfLabel = null; //is the mouse hovering over an edge? which one? MetamapsModel.edgeHoveringOver = false; diff --git a/app/assets/javascripts/Jit/graphsettings.js b/app/assets/javascripts/Jit/graphsettings.js index 5b5646d8..b9002d79 100644 --- a/app/assets/javascripts/Jit/graphsettings.js +++ b/app/assets/javascripts/Jit/graphsettings.js @@ -58,7 +58,7 @@ function graphSettings(type, embed) { }, //Update node positions when dragged onDragMove: function (node, eventInfo, e) { - onDragMoveTopicHandler(node, eventInfo, e); + onDragMoveTopicHandler(node, eventInfo, e); }, onDragEnd: function(node, eventInfo, e) { onDragEndTopicHandler(node, eventInfo, e, false); @@ -67,16 +67,45 @@ function graphSettings(type, embed) { onDragCancelHandler(node, eventInfo, e, false); }, //Implement the same handler for touchscreens + onTouchStart: function (node, eventInfo, e) { + //$jit.util.event.stop(e); //stop default touchmove event + //Mconsole.events.onMouseDown(e, null, eventInfo); + Mconsole.events.touched = true; + touchPos = eventInfo.getPos(); + var canvas = Mconsole.canvas, + ox = canvas.translateOffsetX; + oy = canvas.translateOffsetY, + sx = canvas.scaleOffsetX, + sy = canvas.scaleOffsetY; + touchPos.x *= sx; + touchPos.y *= sy; + touchPos.x += ox; + touchPos.y += oy; + + touchDragNode = node; + }, + //Implement the same handler for touchscreens onTouchMove: function (node, eventInfo, e) { - $jit.util.event.stop(e); //stop default touchmove event - this.onDragMove(node, eventInfo, e); + if (touchDragNode) onDragMoveTopicHandler(touchDragNode, eventInfo, e); + else { + touchPanZoomHandler(eventInfo, e); + Mconsole.labels.hideLabel(Mconsole.graph.getNode(MetamapsModel.showcardInUse)); + } + }, + //Implement the same handler for touchscreens + onTouchEnd: function (node, eventInfo, e) { + + }, + //Implement the same handler for touchscreens + onTouchCancel: function (node, eventInfo, e) { + }, //Add also a click handler to nodes onClick: function (node, eventInfo, e) { if (e.target.id != "infovis-canvas") return false; //topic and synapse editing cards - hideCards(); + if (!Mconsole.events.moved) hideCards(); //clicking on a node, or clicking on blank part of canvas? if (node.nodeFrom) { @@ -84,6 +113,8 @@ function graphSettings(type, embed) { } else if (node && !node.nodeFrom) { selectNodeOnClickHandler(node, e); } else { + //topic and synapse editing cards + if (!Mconsole.events.moved) hideCards(); canvasDoubleClickHandler(eventInfo.getPos(), e); }//if } @@ -500,18 +531,28 @@ function onDragCancelHandler(node, eventInfo, e, centred) { } function onPlaceLabelHandler(domElement, node) { - var style = domElement.style; - var left = parseInt(style.left); - var top = parseInt(style.top); - var w = domElement.offsetWidth; - style.left = (left - w / 2 + 107) + 'px'; - style.top = (top-165) + 'px'; - style.display = ''; - var label = document.getElementById('topic_' + node.id + '_label'); - $(label).show(); - w = label.offsetWidth; - style = label.style; - style.left = (-(w / 2 + 106)) + 'px'; + var style = domElement.style; + var left = parseInt(style.left); + var top = parseInt(style.top); + var w = $('#topic_' + node.id + '_label').width(); + style.left = (left - w / 2) + 'px'; + style.top = (top+20) + 'px'; + style.display = ''; + + // now position the showcard + if (MetamapsModel.showcardInUse != null) { + top = $('#' + MetamapsModel.showcardInUse).css('top'); + left = parseInt($('#' + MetamapsModel.showcardInUse).css('left')); + if (0 != $('#topic_' + MetamapsModel.showcardInUse + '_label').width()) { + MetamapsModel.widthOfLabel = $('#topic_' + MetamapsModel.showcardInUse + '_label').width(); + } + w = MetamapsModel.widthOfLabel/2; + left = (left + w) + 'px'; + $('#showcard').css('top', top); + $('#showcard').css('left', left); + + Mconsole.labels.hideLabel(Mconsole.graph.getNode(MetamapsModel.showcardInUse)); + } } // thanks to http://stackoverflow.com/questions/4338963/ diff --git a/app/assets/javascripts/Jit/jit2.0.0.js b/app/assets/javascripts/Jit/jit2.0.0.js index 7e15717b..0a5fdc9e 100644 --- a/app/assets/javascripts/Jit/jit2.0.0.js +++ b/app/assets/javascripts/Jit/jit2.0.0.js @@ -2591,6 +2591,7 @@ Extras.Classes.Navigation = new Class({ $.event.stop($.event.get(e, win)); var val = this.config.zooming / 1000, ans = 1 + scroll * val; + // START METAMAPS CODE if (ans > 1) { if (5 >= this.canvas.scaleOffsetX) { this.canvas.scale(ans, ans); @@ -2607,6 +2608,8 @@ Extras.Classes.Navigation = new Class({ else if (this.canvas.scaleOffsetX > 0.5) { this.canvas.viz.labels.hideLabels(false); } + // END METAMAPS CODE + // ORIGINAL CODE this.canvas.scale(ans, ans); }, onMouseDown: function(e, win, eventInfo) { diff --git a/app/assets/javascripts/Jit/loadgraphs.js b/app/assets/javascripts/Jit/loadgraphs.js index 2335a4ba..8a1c585b 100644 --- a/app/assets/javascripts/Jit/loadgraphs.js +++ b/app/assets/javascripts/Jit/loadgraphs.js @@ -118,6 +118,25 @@ function initialize(type, loadLater, embed){ else if ( type == "arranged" || type == "chaotic") { Mconsole.animate(chooseAnimate); } + + // prevent touch events on the canvas from default behaviour + $("#infovis-canvas").bind('touchstart', function(event) { + event.preventDefault(); + Mconsole.events.touched = true; + }); + + // prevent touch events on the canvas from default behaviour + $("#infovis-canvas").bind('touchmove', function(event) { + //touchPanZoomHandler(event); + }); + + // prevent touch events on the canvas from default behaviour + $("#infovis-canvas").bind('touchend touchcancel', function(event) { + lastDist = 0; + if (!Mconsole.events.touchMoved && !touchDragNode) hideCurrentCard(); + Mconsole.events.touched = Mconsole.events.touchMoved = false; + touchDragNode = false; + }); }); // end }// if not loadLater diff --git a/app/assets/javascripts/Jit/onCreateLabelHandler.js b/app/assets/javascripts/Jit/onCreateLabelHandler.js index 51a41f93..e960bc7a 100644 --- a/app/assets/javascripts/Jit/onCreateLabelHandler.js +++ b/app/assets/javascripts/Jit/onCreateLabelHandler.js @@ -15,22 +15,6 @@ */ function onCreateLabelHandler(domElement, node) { - var html = generateShowcardHTML(); - html = replaceVariables(html, node); - - var showCard = document.createElement('div'); - showCard.className = 'showcard topic_' + node.id; - if (authorizeToEdit(node)) { - var perm = document.createElement('div'); - perm.className = 'permission canEdit'; - perm.innerHTML = html; - showCard.appendChild(perm); - } else { - showCard.innerHTML = html; - } - showCard.style.display = "none"; - domElement.appendChild(showCard); - // Create a 'name' button and add it to the main node label var nameContainer = document.createElement('span'), style = nameContainer.style; @@ -42,7 +26,7 @@ function onCreateLabelHandler(domElement, node) { style.fontSize = "0.9em"; style.color = "#222222"; - bindCallbacks(showCard, nameContainer, node); + bindNameContainerCallbacks(nameContainer, node); } function generateShowcardHTML() { @@ -273,41 +257,41 @@ function hideCard(node) { $(card).fadeOut('fast', function(){ node.setData('dim', 25, 'current'); - $('.name.topic_' + node.id).show(); + Mconsole.labels.hideLabel(Mconsole.graph.getNode(node.id), true) Mconsole.plot(); }); MetamapsModel.showcardInUse = null; } -function bindCallbacks(showCard, nameContainer, node) { - // add some events to the label - $(showCard).find('img.icon').click(function(){ - hideCard(node); - }); - - $(showCard).find('.scroll').mCustomScrollbar(); +function bindNameContainerCallbacks(nameContainer, node) { + nameContainer.onmouseover = function(){ + $('.name.topic_' + node.id + ' .nodeOptions').css('display','block'); + } + + nameContainer.onmouseout = function(){ + $('.name.topic_' + node.id + ' .nodeOptions').css('display','none'); + } + + var showCard = document.getElementById('showcard'); // add some events to the label $(nameContainer).find('.label').click(function(e){ - $('.name').css('display','block'); - $('.name.topic_' + node.id).css('display','none'); - $('.showcard.topic_' + node.id).fadeIn('fast'); - $('.showcard.topic_' + node.id).find('.scroll').mCustomScrollbar("update"); - node.setData('dim', 1, 'current'); - hideCurrentCard(); - MetamapsModel.showcardInUse = node.id; - Mconsole.plot(); - }); - - nameContainer.onmouseover = function(){ - $('.name.topic_' + node.id + ' .nodeOptions').css('display','block'); - } - - nameContainer.onmouseout = function(){ - $('.name.topic_' + node.id + ' .nodeOptions').css('display','none'); - } + showCard.innerHTML = ''; + + var html = generateShowcardHTML(); + html = replaceVariables(html, node); + + showCard.className = 'showcard topic_' + node.id; + if (authorizeToEdit(node)) { + var perm = document.createElement('div'); + perm.className = 'permission canEdit'; + perm.innerHTML = html; + showCard.appendChild(perm); + } else { + showCard.innerHTML = html; + } //bind best_in_place ajax callbacks $(showCard).find('.best_in_place_metacode').bind("ajax:success", function() { @@ -379,4 +363,24 @@ function bindCallbacks(showCard, nameContainer, node) { else if (permission == "public") el.html("pu"); else if (permission == "private") el.html("pr"); }); + + var top = $('#' + node.id).css('top'); + var left = parseInt($('#' + node.id).css('left')); + var w = $('#topic_' + node.id + '_label').width(); + w = w/2; + left = (left + w) + 'px'; + $('#showcard').css('top', top); + $('#showcard').css('left', left); + + $('.showcard.topic_' + node.id).fadeIn('fast'); + $('.showcard.topic_' + node.id).find('.scroll').mCustomScrollbar(); + node.setData('dim', 1, 'current'); + MetamapsModel.showcardInUse = node.id; + Mconsole.plot(); + Mconsole.labels.hideLabel(Mconsole.graph.getNode(node.id)) + // add some events to the label + $(showCard).find('img.icon').click(function(){ + hideCard(node); + }); + }); } diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 1f5ab3e2..70607ce1 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -21,7 +21,7 @@ // other options are 'graph' var viewMode = "list"; -var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null, gType, tempNode = null, tempInit = false, tempNode2 = null, metacodeIMGinit = false, findOpen = false, analyzeOpen = false, organizeOpen = false, goRealtime = false, mapid = null, mapperm = false; +var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null, gType, tempNode = null, tempInit = false, tempNode2 = null, metacodeIMGinit = false, findOpen = false, analyzeOpen = false, organizeOpen = false, goRealtime = false, mapid = null, mapperm = false, touchPos, touchDragNode; $(document).ready(function() { @@ -69,11 +69,25 @@ var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null, height: '0px' }, 300, function() { sliding1 = false; + menuIsOpen = false; }); } },800); } ); + + var menuIsOpen = false; + $("#mainTitle a").bind('touchend', function(evt) { + if (!menuIsOpen) { + menuIsOpen = true; + var listLength = $('.logo .menu li').length * 28; + $('.footer .menu').animate({ + height: listLength + 'px' + }, 300); + evt.preventDefault(); + evt.stopPropogation(); + } + }); addHoverForSettings(); @@ -99,7 +113,7 @@ var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null, saveLayoutAll(); }); -}); +}); // end document.ready function addHoverForSettings() { // controls the sliding hover of the settings for cards diff --git a/app/assets/stylesheets/ForceDirected.css b/app/assets/stylesheets/ForceDirected.css index 9c4662df..0e70f5da 100644 --- a/app/assets/stylesheets/ForceDirected.css +++ b/app/assets/stylesheets/ForceDirected.css @@ -4,6 +4,7 @@ .label { display:block; + white-space: nowrap; padding: 2px 4px; background:#ddd; opacity:0.8; @@ -13,5 +14,4 @@ span.name { cursor: pointer; position: absolute; - top: 185px; } diff --git a/app/assets/stylesheets/base.css b/app/assets/stylesheets/base.css index c9b3122d..a9bd8a59 100644 --- a/app/assets/stylesheets/base.css +++ b/app/assets/stylesheets/base.css @@ -7,6 +7,9 @@ } .showcard, #showcard { + position:absolute; + display:none; + margin-top: -181px; width:216px; height:320px; color:#FFF; diff --git a/app/views/main/console.html.erb b/app/views/main/console.html.erb index 0e744d83..83f96661 100644 --- a/app/views/main/console.html.erb +++ b/app/views/main/console.html.erb @@ -24,6 +24,7 @@
+
<% if authenticated? %> diff --git a/app/views/maps/show.html.erb b/app/views/maps/show.html.erb index 00645ef4..c83538b4 100644 --- a/app/views/maps/show.html.erb +++ b/app/views/maps/show.html.erb @@ -43,6 +43,7 @@
+
diff --git a/app/views/topics/show.html.erb b/app/views/topics/show.html.erb index 93806d8d..10fcf216 100644 --- a/app/views/topics/show.html.erb +++ b/app/views/topics/show.html.erb @@ -31,6 +31,7 @@
+