add a useful comment
[mussa.git] / alg / glseqbrowser.cpp
index 79acb4068c64fd224def7b6f06dc93ee11bacdba..04cc792ec441e3eeb375fb2ac47bf842d509b3c0 100644 (file)
@@ -1,6 +1,7 @@
 #include "alg/glseqbrowser.hpp"
 #include "mussa_exceptions.hpp"
 
+#include <math.h>
 #include <iostream>
 #include <sstream>
 #include <stdexcept>
@@ -25,7 +26,8 @@ GlSeqBrowser::GlSeqBrowser(const GlSeqBrowser& gt)
     viewport_center(gt.viewport_center),
     zoom_level(gt.zoom_level),
     color_mapper(gt.color_mapper),
-    track_container(gt.track_container)
+    track_container(gt.track_container),
+    path_segments(gt.path_segments)
 {
 }
 
@@ -223,6 +225,15 @@ float GlSeqBrowser::right() const
   }
 }
 
+float GlSeqBrowser::get_pixel_width() const
+{
+  GLint viewport[4];
+  glGetIntegerv(GL_VIEWPORT, viewport);
+  GLint vp_width = viewport[3]; // grab the viewport width
+  
+  return round((cur_ortho.right-cur_ortho.left)/vp_width);
+}  
+
 void GlSeqBrowser::setViewportCenter(float x)
 {
   update_viewport(x, zoom_level);
@@ -254,6 +265,16 @@ float GlSeqBrowser::viewportWidth() const
   return cur_ortho.right - cur_ortho.left;
 }
 
+int GlSeqBrowser::viewportPixelHeight() const
+{
+  return viewport_size.y;
+}
+
+int GlSeqBrowser::viewportPixelWidth() const
+{
+  return viewport_size.x;
+}
+
 double GlSeqBrowser::zoomOut()
 {
 
@@ -440,11 +461,12 @@ list<TrackRegion> GlSeqBrowser::selectedTracks() const
 
 //! copy sequence from selected track using formating function
 template<class Item>
-void GlSeqBrowser::copySelectedTracks(std::list<Item>& result, 
+size_t GlSeqBrowser::copySelectedTracks(std::list<Item>& result, 
              Item (*formatter)(boost::shared_ptr<Sequence> s, 
                                int left, 
                                int right))
 {
+  size_t base_pairs_copied = 0;
   result.clear();
 
   for(selected_track_iterator track_i = selected_tracks.begin();
@@ -460,12 +482,14 @@ void GlSeqBrowser::copySelectedTracks(std::list<Item>& result,
       // we should be safe
       boost::shared_ptr<Sequence> seq = track_container[track_index]->sequence();
       result.push_back(formatter(seq, track_i->left, track_i->right));
+      base_pairs_copied += max(track_i->right-track_i->left, 0);
     }
   }
+  return base_pairs_copied;
 }
 
 //! copy sequence from selected tracks as FASTA sequences
-void GlSeqBrowser::copySelectedTracksAsFasta(std::string& copy_buffer)
+size_t GlSeqBrowser::copySelectedTracksAsFasta(std::string& copy_buffer)
 {
   std::list<std::string> result;
   struct AsFasta {
@@ -481,7 +505,7 @@ void GlSeqBrowser::copySelectedTracksAsFasta(std::string& copy_buffer)
       return s.str();
     }
   };
-  copySelectedTracks(result, AsFasta::formatter);
+  size_t base_pairs_copied = copySelectedTracks(result, AsFasta::formatter);
   // I wish there was some way to use for_each and bind here
   for (list<string>::iterator result_i = result.begin();
        result_i != result.end();
@@ -489,10 +513,11 @@ void GlSeqBrowser::copySelectedTracksAsFasta(std::string& copy_buffer)
   {
     copy_buffer.append(*result_i);
   }
+  return base_pairs_copied;
 }
 
 //! copy sequence from selected tracks as new sequences
-void GlSeqBrowser::copySelectedTracksAsSequences(std::list<Sequence>& result)
+size_t GlSeqBrowser::copySelectedTracksAsSequences(std::list<Sequence>& result)
 {
   struct AsSequence {
     static Sequence formatter(boost::shared_ptr<Sequence> seq, 
@@ -502,10 +527,10 @@ void GlSeqBrowser::copySelectedTracksAsSequences(std::list<Sequence>& result)
       return seq->subseq(left, right-left+1);
     }
   };
-  copySelectedTracks(result, AsSequence::formatter);
+  return copySelectedTracks(result, AsSequence::formatter);
 }
 
-void GlSeqBrowser::copySelectedTracksAsSeqLocation(
+size_t GlSeqBrowser::copySelectedTracksAsSeqLocation(
     std::list<SequenceLocation>& result)
 {
   struct AsSeqLocation {
@@ -516,11 +541,11 @@ void GlSeqBrowser::copySelectedTracksAsSeqLocation(
       return SequenceLocation(seq, left, right);
     }
   };
-  copySelectedTracks(result, AsSeqLocation::formatter);
+  return copySelectedTracks(result, AsSeqLocation::formatter);
 }
 
 //! copy sequence from selected tracks as plain sequences
-void GlSeqBrowser::copySelectedTracksAsString(std::string& copy_buffer)
+size_t GlSeqBrowser::copySelectedTracksAsString(std::string& copy_buffer)
 {
   std::list<string> result;
   struct AsString {
@@ -529,12 +554,12 @@ void GlSeqBrowser::copySelectedTracksAsString(std::string& copy_buffer)
                             int right)
     {
       stringstream s;
-      s << seq->subseq(left, right-left+1) << std::endl;
+      s << seq->subseq(left, right-left+1);
       return s.str();
     }
   };
 
-  copySelectedTracks(result, AsString::formatter);
+  size_t base_pairs_copied = copySelectedTracks(result, AsString::formatter);
   // I wish there was some way to use for_each and bind here
   for (list<string>::iterator result_i = result.begin();
        result_i != result.end();
@@ -542,7 +567,7 @@ void GlSeqBrowser::copySelectedTracksAsString(std::string& copy_buffer)
   {
     copy_buffer.append(*result_i);
   }
-
+  return base_pairs_copied;
 }
 
 void GlSeqBrowser::centerOnPath(const vector<int>& paths)
@@ -650,6 +675,8 @@ void GlSeqBrowser::draw_segments() const
   glEnable(GL_BLEND);
   glDepthMask(GL_FALSE);
   const float zdepth = -1.0;
+  const float min_segment_width = max((float)(1.0), get_pixel_width());
+  
   // each vector contains path_segment_maps of all the connections
   // between this track and the next
   path_segment_map_vector::const_iterator psmv_i;
@@ -677,12 +704,14 @@ void GlSeqBrowser::draw_segments() const
                        back_inserter(selected));
 
       if (not s.reversed) {
+        // forward
         if (selected_paths.size() == 0 or selected.size() > 0) {
           glColor4f(1.0, 0.0, 0.0, 1.0);
         } else {
           glColor4f(1.0, 0.7, 0.7, 0.4);
         }
       } else { 
+        // reverse
         if (selected_paths.size() == 0 or selected.size() > 0) {
           glColor4f(0.0, 0.0, 1.0, 1.0);
         } else {
@@ -695,10 +724,10 @@ void GlSeqBrowser::draw_segments() const
                         + track_container[path_index]->x();
       float seq_end_x = s.end.x
                       + track_container[path_index+1]->x();
-      if (s.length <= 1) {
-        // use lines for elements of length <=1.
+      if (s.length <= min_segment_width) {
+        // use lines for elements of length <=1 or < 1 pixel.
         // and try to center the line
-        const float offset = 0.5;
+        const float offset = s.length * 0.5;
         glBegin(GL_LINES);
           glVertex3f(seq_start_x+offset, s.start.y, -1);
           glVertex3f(seq_end_x  +offset, s.end.y, -1);