Marquee now selects in any direction. Deselecting of nodes on multpiple nodes selecte...
[scpubgit/stemmaweb.git] / root / js / relationship.js
index 9782e82..e822d70 100644 (file)
@@ -5,6 +5,17 @@ var start_element_height = 0;
 var reltypes = {};
 var readingdata = {};
 
+function arrayUnique(array) {
+    var a = array.concat();
+    for(var i=0; i<a.length; ++i) {
+        for(var j=i+1; j<a.length; ++j) {
+            if(a[i] === a[j])
+                a.splice(j--, 1);
+        }
+    }
+    return a;
+};
+
 function getTextURL( which ) {
        return basepath + textid + '/' + which;
 }
@@ -377,6 +388,10 @@ function node_obj(ellipse) {
       self.node_elements = node_elements_for(self.ellipse);
   }
 
+  this.get_witnesses = function() {
+      return readingdata[self.get_id()].witnesses
+  }
+  
   self.set_draggable( true );
 }
 
@@ -591,33 +606,40 @@ function Marquee() {
     
     var self = this;
     
+    this.x = 0;
+    this.y = 0;
+    this.dx = 0;
+    this.dy = 0;
     this.enlargementOffset = $('#svgenlargement').offset();
     this.svg_rect = $('#svgenlargement svg').svg('get');
 
     this.show = function( event ) {
         // TODO: uncolor possible selected
         // TODO: unless SHIFT?
+        self.x = event.clientX;
+        self.y = event.clientY;
         p = svg_root.createSVGPoint();
         p.x = event.clientX - self.enlargementOffset.left;
         p.y = event.clientY - self.enlargementOffset.top;
-        // NB: I think next line is officially needed, it's only 
-        // coincidentally that viewport and svg scale 1 to 1 initially
-        // and therefor we don't need a transform? 
-        // p.matrixTransform( svg_root_element.getCTM().inverse() );
         self.svg_rect.rect( p.x, p.y, 0, 0, { fill: 'black', 'fill-opacity': '0.1', stroke: 'black', 'stroke-dasharray': '4,2', strokeWidth: '0.02em', id: 'marquee' } );
     };
 
     this.expand = function( event ) {
+        self.dx = (event.clientX - self.x);
+        self.dy = (event.clientY - self.y);
         var rect = $('#marquee');
-        if( rect.length != 0 ) {
-            var pX = (event.clientX - self.enlargementOffset.left) - rect.attr("x");;
-            var pY = (event.clientY - self.enlargementOffset.top) - rect.attr("y");;
-            rect.attr("width", pX);
-            rect.attr("height", pY);
+        if( rect.length != 0 ) {            
+            var rect_w =  Math.abs( self.dx );
+            var rect_h =  Math.abs( self.dy );
+            var rect_x = self.x - self.enlargementOffset.left;
+            var rect_y = self.y - self.enlargementOffset.top;
+            if( self.dx < 0 ) { rect_x = rect_x - rect_w }
+            if( self.dy < 0 ) { rect_y = rect_y - rect_h }
+            rect.attr("x", rect_x).attr("y", rect_y).attr("width", rect_w).attr("height", rect_h);
         }
     };
     
-    this.hide = function() {
+    this.select = function() {
         var rect = $('#marquee');
         if( rect.length != 0 ) {
             var left = $('#marquee').offset().left;
@@ -634,6 +656,7 @@ function Marquee() {
             p.y=bottom;
             var cx_max = p.matrixTransform(tf).x;
             var cy_max = p.matrixTransform(tf).y;
+            var witnesses = [];
             $('#svgenlargement ellipse').each( function( index ) {
                 var cx = parseInt( $(this).attr('cx') );
                 var cy = parseInt( $(this).attr('cy') );
@@ -641,14 +664,25 @@ function Marquee() {
                     if( cy > cy_min && cy < cy_max) {
                         // we actually heve no real 'selected' state for nodes, except coloring
                         $(this).attr( 'fill', '#ffccff' );
+                        var this_witnesses = $(this).data( 'node_obj' ).get_witnesses();
+                        witnesses = arrayUnique( witnesses.concat( this_witnesses ) );
                     }
                 }
             });
-            // select here
+            if( $('ellipse[fill="#ffccff"]').size() > 0 ) {
+                $.each( witnesses, function( index, value ) {
+                    $('#multipleselect-form').append( '<input type="checkbox" name="witnesses" value="' + value + '">' + value + '<br>' );
+                });
+                $('#multipleselect-form').dialog( 'open' );
+            }
             self.svg_rect.remove( $('#marquee') );
         }
     };
     
+    this.unselect = function() {
+        $('ellipse[fill="#ffccff"]').attr( 'fill', '#fff' );
+    }
+     
 }
 
 
@@ -678,7 +712,7 @@ $(document).ready(function () {
     event.preventDefault();
     return false;
   }).mouseup(function (event) {
-    marquee.hide(); 
+    marquee.select(); 
     $(this).data('down', false);
   }).mousemove(function (event) {
     if( timer != null ) { clearTimeout(timer); } 
@@ -813,6 +847,7 @@ $(document).ready(function () {
         global: function () { delete_relation( true ); },
         delete: function() { delete_relation( false ); }
   };   
+  
   $( "#delete-form" ).dialog({
     autoOpen: false,
     height: 135,
@@ -820,8 +855,12 @@ $(document).ready(function () {
     modal: false,
     create: function(event, ui) {
        // TODO What is this logic doing?
+       // This scales the buttons in the dialog and makes it look proper
+       // Not sure how essential it is, does anything break if it's not here?
         var buttonset = $(this).parent().find( '.ui-dialog-buttonset' ).css( 'width', '100%' );
         buttonset.find( "button:contains('Cancel')" ).css( 'float', 'right' );
+       // A: This makes sure that the pop up delete relation dialogue for a hovered over
+       // relation auto closes if the user doesn't engage (mouseover) with it.
         var dialog_aria = $("div[aria-labelledby='ui-dialog-title-delete-form']");  
         dialog_aria.mouseenter( function() {
             if( mouseWait != null ) { clearTimeout(mouseWait) };
@@ -852,6 +891,31 @@ $(document).ready(function () {
     close: function() {}
   });
 
+  var multipleselect_buttonset = {
+        cancel: function() { $( this ).dialog( "close" ); },
+        button1: function () {  },
+        button2: function() {  }
+  };   
+
+  $( "#multipleselect-form" ).dialog({
+    autoOpen: false,
+    height: 150,
+    width: 250,
+    modal: true,
+    create: function(event, ui) {
+        var buttonset = $(this).parent().find( '.ui-dialog-buttonset' ).css( 'width', '100%' );
+        buttonset.find( "button:contains('Cancel')" ).css( 'float', 'right' );
+    },
+    open: function() {
+        $( this ).dialog( "option", "width", 200 );
+        $( this ).dialog( "option", "buttons",
+            [{ text: "Button_1", click: multipleselect_buttonset['button1'] },
+             { text: "Button_2", click: multipleselect_buttonset['button2'] },
+             { text: "Cancel", click: multipleselect_buttonset['cancel'] }] );
+    },
+    close: function() { marquee.unselect(); }
+  });
+
   // Helpers for relationship deletion
   
   function delete_relation( scopewide ) {