WhatsThis update
[mussa.git] / alg / glsequence.cpp
index 8af0adbe03fbdbc3af960e8efa9d40ad626f6af9..6cb1b578fc211c59bcd39c68f721b816116c27fc 100644 (file)
@@ -6,7 +6,8 @@
 #include <stdexcept>
 using namespace std;
 
-GlSequence::GlSequence(const Sequence &s, AnnotationColors& cm) 
+GlSequence::GlSequence(boost::shared_ptr<Sequence> s, 
+                       boost::shared_ptr<AnnotationColors> cm) 
   : seq(s),
     seq_x(0.0), 
     seq_y(0.0), 
@@ -33,7 +34,7 @@ GlSequence::GlSequence(const GlSequence &s)
 GlSequence &GlSequence::operator=(const GlSequence & s)
 {
   if (this != &s) {
-    const_cast<Sequence &>(seq) = s.seq;
+    seq = s.seq;
     seq_x = s.seq_x;
     seq_y = s.seq_y;
     seq_z = s.seq_z;
@@ -45,7 +46,7 @@ GlSequence &GlSequence::operator=(const GlSequence & s)
   return *this;
 }
 
-const Sequence& GlSequence::sequence() const
+boost::shared_ptr<Sequence> GlSequence::sequence()
 {
   return seq;
 }
@@ -62,7 +63,7 @@ GLfloat GlSequence::x() const
 
 GLfloat GlSequence::right() const
 {
-  return length()+seq_x;
+  return size()+seq_x;
 }
 
 void GlSequence::setY(GLfloat value)
@@ -80,9 +81,9 @@ GLfloat GlSequence::height() const
   return seq_height;
 }
 
-GLfloat GlSequence::length() const
+GLfloat GlSequence::size() const
 {
-  return seq.size();
+  return seq->size();
 }
 
 Sequence::size_type GlSequence::leftbase(GLfloat left) const
@@ -90,8 +91,8 @@ Sequence::size_type GlSequence::leftbase(GLfloat left) const
   left = ceil(left - seq_x);
   if (left < 0)
     return 0;
-  else if (left > seq.size() )
-    return seq.size();
+  else if (left > seq->size() )
+    return seq->size();
   else
     return (Sequence::size_type)left;
 }
@@ -99,8 +100,8 @@ Sequence::size_type GlSequence::leftbase(GLfloat left) const
 Sequence::size_type GlSequence::rightbase(GLfloat right) const
 {
   right = floor(right) - seq_x;
-  if (right > seq.size())
-    return seq.size();
+  if (right > seq->size())
+    return seq->size();
   else if ( right < 0) 
     return 0;
   else 
@@ -109,30 +110,30 @@ Sequence::size_type GlSequence::rightbase(GLfloat right) const
 
 Sequence::const_iterator GlSequence::sequence_begin() const
 {
-  return seq.begin();
+  return seq->begin();
 }
 
 Sequence::const_iterator GlSequence::sequence_end() const
 {
-  return seq.end();
+  return seq->end();
 }
 
 Sequence::const_iterator 
 GlSequence::sequence_begin(GLfloat left, GLfloat right) const
 {
-  if ( leftbase(left) > seq.size() or left > right )
-    return seq.end();
+  if ( leftbase(left) > seq->size() or left > right )
+    return seq->end();
   else
-    return seq.begin() + leftbase(left);
+    return seq->begin() + leftbase(left);
 }
 
 Sequence::const_iterator 
 GlSequence::sequence_end(GLfloat left, GLfloat right) const
 {
-  if ( rightbase(right) > seq.size() or left > right )
-    return seq.end();
+  if ( rightbase(right) > seq->size() or left > right )
+    return seq->end();
   else
-    return seq.begin() + rightbase(right); 
+    return seq->begin() + rightbase(right); 
 }
 
 
@@ -148,7 +149,6 @@ Color GlSequence::color()
   return drawColor;
 }
 
-
 int GlSequence::get_viewport_width_in_pixels()
 {
   GLint viewport[4];
@@ -221,21 +221,21 @@ void GlSequence::draw_track(GLfloat left, GLfloat right) const
 {
   glColor3fv(drawColor.get());
   // draw main sequence track
-  draw_box(left, right, seq_x, seq_x+seq.size(), seq_height, 0.0);
+  draw_box(left, right, seq_x, seq_x+seq->size(), seq_height, 0.0);
 }
 
 void GlSequence::draw_annotations(GLfloat left, GLfloat right) const
 {
   // draw annotations
   GLfloat annotation_z = seq_z + 10.0;
-  const std::list<annot>& annots = seq.annotations();
-  const std::list<motif>& motifs = seq.motifs();
+  const std::list<annot>& annots = seq->annotations();
+  const std::list<motif>& motifs = seq->motifs();
   for (std::list<annot>::const_iterator annot_itor = annots.begin();
        annot_itor != annots.end();
        ++annot_itor)
   {
     glColor3f(0.0, 0.8, 0.0);
-    draw_box(left, right, seq_x+annot_itor->start, seq_x+annot_itor->end, 
+    draw_box(left, right, seq_x+annot_itor->begin, seq_x+annot_itor->end, 
              seq_height, annotation_z);
   }
   // if motifs?
@@ -243,13 +243,14 @@ void GlSequence::draw_annotations(GLfloat left, GLfloat right) const
        motifs_itor != motifs.end();
        ++motifs_itor)
   {
-    glColor3fv(color_mapper.lookup("motif", motifs_itor->sequence).get());
-    draw_box(left, right, seq_x+motifs_itor->start, seq_x+motifs_itor->end, 
+    glColor3fv(color_mapper->lookup("motif", motifs_itor->sequence).get());
+    draw_box(left, right, seq_x+motifs_itor->begin, seq_x+motifs_itor->end, 
              seq_height, annotation_z+1.0);
   }
 
 }
 
+// this way of drawing characters, came from the red open gl book
 const int PT = 1;
 const int STROKE = 2;
 const int END =3;
@@ -282,6 +283,9 @@ CP Cdata[] = {
 CP Xdata[] = {{ 0, 5, PT}, {5, -5,STROKE},{0,-5,PT},{5, 5, END}};
 CP Ndata[] = {{ 0, -5, PT}, {0, 5, PT}, {5, -5, PT}, {5, 5, END}};
 
+//! the maximum width used for a charcter glyph
+const int max_glyph_width = 5; // unit ( glyph_coord )
+
 static void drawLetter(CP *l, GLfloat z)
 {
   glBegin(GL_LINE_STRIP);
@@ -317,14 +321,19 @@ void GlSequence::draw_sequence(GLfloat left, GLfloat right) const
   Sequence::const_iterator seq_itor = sequence_begin(left, right);
   Sequence::const_iterator seq_end = sequence_end(left, right);
   Sequence::size_type basepair = 0;
+  const float bp_per_world = 1.0; //( world coord )
+  const float glyph_x_scale = 0.125; // unit = ( world coord / glyph coord )
+  // compute how much space there should be to either size of a letter
+  const float glyph_margin = (bp_per_world - glyph_x_scale * max_glyph_width) 
+                           / 2.0;  
 
   assert(seq_end - seq_itor >= 0);
   while(seq_itor != seq_end)
   {
-    assert ( basepair < seq.size() );
+    assert ( basepair < seq->size() );
     glPushMatrix();
-    glTranslatef( seq_x+leftbase(left) + basepair, seq_y, 1.0 );
-    glScalef(0.1, 1.0, 1.0);
+    glTranslatef( seq_x+leftbase(left) + basepair + glyph_margin, seq_y, 1.0 );
+    glScalef(glyph_x_scale, 1.0, 1.0);
     switch (*seq_itor) {
       case 'A': case 'a':
         drawLetter(Adata, z);