#include <stdexcept>
using namespace std;
-GlSequence::GlSequence(const Sequence &s, AnnotationColors& cm)
- : seq(s),
+GlSequence::GlSequence(const Sequence &s,
+ boost::shared_ptr<AnnotationColors> cm)
+ : Sequence(s),
seq_x(0.0),
seq_y(0.0),
seq_z(1.0),
seq_height(12.0),
color_mapper(cm),
- drawColor(0.0, 0.0, 0.0),
- char_pix_per_world_unit(5.0)
+ drawColor(new Color(0.0, 0.0, 0.0)),
+ char_pix_per_world_unit(2.5)
{
}
GlSequence::GlSequence(const GlSequence &s)
- : seq(s.seq),
+ : Sequence(s),
seq_x(s.seq_x),
seq_y(s.seq_y),
seq_z(s.seq_z),
{
}
+GlSequence::GlSequence(const GlSequence *s)
+ : Sequence(s),
+ seq_x(s->seq_x),
+ seq_y(s->seq_y),
+ seq_z(s->seq_z),
+ seq_height(s->seq_height),
+ color_mapper(s->color_mapper),
+ drawColor(s->drawColor),
+ char_pix_per_world_unit(s->char_pix_per_world_unit)
+{
+}
+
GlSequence &GlSequence::operator=(const GlSequence & s)
{
if (this != &s) {
- const_cast<Sequence &>(seq) = s.seq;
+ Sequence::operator=(s);
seq_x = s.seq_x;
seq_y = s.seq_y;
seq_z = s.seq_z;
return *this;
}
-const Sequence& GlSequence::sequence() const
-{
- return seq;
-}
-
void GlSequence::setX(GLfloat value)
{
seq_x = value;
GLfloat GlSequence::right() const
{
- return length()+seq_x;
+ return size()+seq_x;
}
void GlSequence::setY(GLfloat value)
return seq_height;
}
-GLfloat GlSequence::length() const
+GLfloat GlSequence::size() const
{
- return seq.size();
+ return Sequence::size();
}
Sequence::size_type GlSequence::leftbase(GLfloat left) const
{
- left = ceil(left) - seq_x;
+ left = ceil(left - seq_x);
if (left < 0)
return 0;
- else if (left > seq.size() )
- return seq.size();
+ else if (left > Sequence::size() )
+ return Sequence::size();
else
return (Sequence::size_type)left;
}
Sequence::size_type GlSequence::rightbase(GLfloat right) const
{
right = floor(right) - seq_x;
- if (right > seq.size())
- return seq.size();
+ if (right > Sequence::size())
+ return Sequence::size();
else if ( right < 0)
return 0;
else
return (Sequence::size_type)right;
}
-Sequence::const_iterator GlSequence::sequence_begin() const
-{
- return seq.begin();
-}
-
-Sequence::const_iterator GlSequence::sequence_end() const
-{
- return seq.end();
-}
-
Sequence::const_iterator
-GlSequence::sequence_begin(GLfloat left, GLfloat right) const
+GlSequence::region_begin(GLfloat left, GLfloat right) const
{
- if ( leftbase(left) > seq.size() or left > right )
- return seq.end();
+ if ( leftbase(left) > Sequence::size() or left > right )
+ return Sequence::end();
else
- return seq.begin() + leftbase(left);
+ return Sequence::begin() + leftbase(left);
}
Sequence::const_iterator
-GlSequence::sequence_end(GLfloat left, GLfloat right) const
+GlSequence::region_end(GLfloat left, GLfloat right) const
{
- if ( rightbase(right) > seq.size() or left > right )
- return seq.end();
+ if ( rightbase(right) > Sequence::size() or left > right )
+ return Sequence::end();
else
- return seq.begin() + rightbase(right);
+ return Sequence::begin() + rightbase(right);
}
+GlSequence GlSequence::subseq(size_type start, size_type count) const
+{
+ GlSequence new_seq(*this);
+ new_seq.seq = seq->subseq(start, count);
+ copy_children(new_seq, start, count);
+
+ return new_seq;
+}
//! set default track draw color
-void GlSequence::setColor(Color &c)
+void GlSequence::setColor(boost::shared_ptr<Color> &c)
{
drawColor = c;
}
//! get default track draw color
-Color GlSequence::color()
+boost::shared_ptr<Color> GlSequence::color()
{
return drawColor;
}
-
-int GlSequence::get_viewport_pixel_width()
+int GlSequence::get_viewport_width_in_pixels()
{
- int viewport[4];
+ GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
return viewport[3]; // grab the viewport width
}
+GLfloat GlSequence::pixelWidth(GLfloat left, GLfloat right) const
+{
+ return pixelWidth(left, right, get_viewport_width_in_pixels());
+}
+
+GLfloat
+GlSequence::pixelWidth(GLfloat left, GLfloat right, int vp_width) const
+{
+ return round((right-left)/vp_width);
+}
+
+bool GlSequence::is_sequence_renderable(GLfloat left, GLfloat right) const
+{
+ return is_sequence_renderable(left, right, get_viewport_width_in_pixels());
+}
+
bool GlSequence::is_sequence_renderable(GLfloat left,
GLfloat right,
int viewport_width) const
{
- // if called with default argument, go get the viewable width
- if (viewport_width == -1) {
- viewport_width = get_viewport_pixel_width();
- }
GLfloat world_width = right - left;
GLfloat pixels_needed = (char_pix_per_world_unit * world_width);
draw_annotations(left, right);
}
-void GlSequence::draw_box(GLfloat left, GLfloat right,
+void GlSequence::draw_box(GLfloat world_left, GLfloat world_right,
+ GLfloat left, GLfloat right,
GLfloat height, GLfloat z) const
{
+ GLfloat pixel_width = pixelWidth(world_left, world_right);
GLfloat offset = height/2.0;
GLfloat top = seq_y + offset;
GLfloat bottom = seq_y - offset;
-
+
+ // make our box be at least 1 pixel
+ if ((right-left) < pixel_width) {
+ right = left + pixel_width;
+ }
glBegin(GL_QUADS);
glVertex3f(left, top, z);
glVertex3f(left, bottom, z);
void GlSequence::draw_track(GLfloat left, GLfloat right) const
{
- glColor3fv(drawColor.get());
+ glColor3fv(drawColor->get());
// draw main sequence track
- draw_box(seq_x, seq_x+seq.size(), seq_height, 0.0);
+ draw_box(left, right, seq_x, seq_x+Sequence::size(), seq_height, 0.0);
}
void GlSequence::draw_annotations(GLfloat left, GLfloat right) const
{
// draw annotations
- glLineWidth(seq_height);
- GLfloat annotation_z = seq_z + 1.0;
- const std::list<annot>& annots = seq.annotations();
- const std::list<motif>& motifs = seq.motifs();
+ GLfloat annotation_z = seq_z + 10.0;
+ const std::list<annot>& annots = Sequence::annotations();
+ const std::list<motif>& motifs = Sequence::motifs();
for (std::list<annot>::const_iterator annot_itor = annots.begin();
annot_itor != annots.end();
- ++annot_itor, ++annotation_z)
+ ++annot_itor)
{
- glColor3f(0.0, 0.5, 0.0);
- draw_box(seq_x+annot_itor->start, seq_x+annot_itor->end,
+ glColor3f(0.0, 0.8, 0.0);
+ draw_box(left, right, seq_x+annot_itor->begin, seq_x+annot_itor->end,
seq_height, annotation_z);
}
// if motifs?
for (std::list<motif>::const_iterator motifs_itor = motifs.begin();
motifs_itor != motifs.end();
- ++motifs_itor, ++annotation_z)
+ ++motifs_itor)
{
- glColor3fv(color_mapper.lookup("motif", motifs_itor->sequence).get());
- draw_box(seq_x+motifs_itor->start, seq_x+motifs_itor->end,
- seq_height, annotation_z);
+ 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;
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);
{
// FIXME: basically this needs to be greater than the number of annotations
const GLfloat z = 30;
- glLineWidth(0.3);
- glColor3fv(drawColor.get());
+ glLineWidth(1);
+ glColor3fv(drawColor->get());
- Sequence::const_iterator seq_itor = sequence_begin(left, right);
- Sequence::const_iterator seq_end = sequence_end(left, right);
+ Sequence::const_iterator seq_itor = region_begin(left, right);
+ Sequence::const_iterator seq_end = region_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 < Sequence::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);