default_policy.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:72k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: default_policy.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 21:12:33  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.41
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: default_policy.cpp,v 1000.3 2004/06/01 21:12:33 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Authors:  Vlad Lebedev
  35.  *
  36.  * File Description:
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbistd.hpp>
  41. #include <gui/widgets/seq_graphic/default_policy.hpp>
  42. #include <gui/objutils/label.hpp>
  43. #include <objects/seqfeat/Cdregion.hpp>
  44. #include <objects/seqfeat/Gb_qual.hpp>
  45. #include <objects/seqfeat/Imp_feat.hpp>
  46. #include <objects/seqres/Byte_graph.hpp>
  47. #include <objects/seqres/Int_graph.hpp>
  48. #include <objects/seqres/Real_graph.hpp>
  49. #include <gui/config/feat_config_list.hpp>
  50. #include <objmgr/scope.hpp>
  51. #include <objmgr/util/feature.hpp>
  52. #include <objmgr/util/sequence.hpp>
  53. #include <objtools/alnmgr/alnmix.hpp>
  54. #include <serial/iterator.hpp>
  55. #include <util/sequtil/sequtil_manip.hpp>
  56. BEGIN_NCBI_SCOPE
  57. USING_SCOPE(objects);
  58. // temporary, until a method for fast
  59. // retrieving of annotations is available
  60. static const int  kSeqAnnotCount      =  20;
  61. // size of an alignment row
  62. static const int kAlnRowHeight       =  13;
  63. // size of a single row in alignment
  64. static const int kAlnElementHeight   =  3;
  65. // size of a single row in alignment
  66. static const int kPWAlignHeight =  6;
  67. // width of a column small
  68. static const int kLabelsColWidth     = 100;
  69. // width of a feature label small
  70. static const int kLabelsMaxWidth     = 90;
  71. // at this point sequence will fit
  72. static const TModelUnit kPixPerBase4Sequence = 8.0f;
  73. TModelUnit kCommentFontSize = 0.0f;
  74. // 3 pixels befween layout objects
  75. static const TModelUnit kSpacerSize   = 3.0f;
  76. // Max number of unique library IDs for mate pairs
  77. static const float kMaxLibraryIDCount = 8.0f; 
  78. CDefaultPolicy::CDefaultPolicy()
  79.     : m_Font_Bitmap9x15(CGlBitmapFont::eBitmap9x15),
  80.       m_Font_Helv10(CGlBitmapFont::eHelvetica10),
  81.       m_Font_Helv8(CGlBitmapFont::eHelvetica8)
  82. {
  83.     m_MinLabelWidth  = TVPUnit(m_Font_Helv10.TextWidth("AA"));
  84.     m_ColorTable     = CGlColorTable(kSeqAnnotCount, 0.5f, 0.75f);
  85.     
  86.     
  87.     kCommentFontSize = m_Font_Helv10.TextHeight();
  88. }
  89. void CDefaultPolicy::SetHandle(const CBioseq_Handle& handle)
  90. {
  91.     m_Handle = handle;
  92.     m_Annots.clear();
  93. }
  94. void CDefaultPolicy::SetConfig(CSeqGraphicConfig* config)
  95. {
  96.     m_ConfigSettings = config;
  97. }
  98. void CDefaultPolicy::SetHitPoint(TModelPoint click)
  99. {
  100.     m_LastClick = click;
  101. }
  102. void CDefaultPolicy::SetActiveArea(TAreaVector* p_area)
  103. {
  104.     m_ActiveAreas = p_area;
  105. }
  106.     
  107. // retrieve a set of labels for a given feature
  108. void CDefaultPolicy::x_GetLabels(const CSeq_feat& feat,
  109.                                  CScope& scope,
  110.                                  string* label_type,
  111.                                  string* label_content,
  112.                                  string* label_both) const
  113. {
  114.     if (feat.IsSetProduct()) {
  115.         CLabel::GetLabel(feat.GetProduct(), label_both,
  116.                          CLabel::eDefault, &scope);
  117.         *label_both += ": ";
  118.         *label_type    = *label_both;
  119.         *label_content = *label_both;
  120.         feature::GetLabel(feat, label_both,    feature::eContent, &scope);
  121.         feature::GetLabel(feat, label_type,    feature::eType,    &scope);
  122.         feature::GetLabel(feat, label_content, feature::eContent, &scope);
  123.     } else {
  124.         feature::GetLabel(feat, label_both,    feature::eBoth,    &scope);
  125.         feature::GetLabel(feat, label_type,    feature::eType,    &scope);
  126.         feature::GetLabel(feat, label_content, feature::eContent, &scope);
  127.     }
  128. }
  129. void CDefaultPolicy::x_SetFeatureColor(const CLayoutFeat* feat) const
  130. {
  131.     CGlColor color;
  132.     if (dynamic_cast<const CLayoutProtProd*>(feat)) {
  133.         color = m_ConfigSettings->GetElementColor(CSeqGraphicColorConfig::eFG_ProtProduct);
  134.     } else {
  135.         const CSeqFeatData& data = feat->GetFeature().GetData();
  136.         color = m_ConfigSettings->GetColor(data.Which(), data.GetSubtype());
  137.     }
  138.     glColor4f(color.GetRed(), color.GetGreen(), color.GetBlue(), 0.65f);
  139. }
  140. void CDefaultPolicy::x_DrawAlignmentSmear(CGlPane& pane, const CLayoutAlignSmear* layout_smear, 
  141.                 GLfloat row_y, EObj_IterMode mode, bool selected) const
  142. {
  143.     const TModelRect& rcV = pane.GetVisibleRect();
  144.     const TModelRect& rcM = pane.GetModelLimitsRect();
  145.     const CAlignmentSmear& smear = layout_smear->GetAlignSmear();
  146.     TModelUnit offsetX = pane.GetOffsetX();
  147.     TModelUnit offsetY = pane.GetOffsetY();
  148.     GLfloat th = m_Font_Helv10.TextHeight();
  149.     GLfloat title_y  = row_y + th + 1;
  150.     GLfloat line_y1  = title_y + 3;
  151.     GLfloat line_y2  = line_y1 + th + 2;
  152.     GLfloat line_ym  = line_y1 + (th + 2) / 2;
  153.     GLfloat strand_y = line_y1 + th;
  154.     GLfloat off      = rcM.Top() > 0 ? th - 1 : 0;
  155.     CGlColor    minColor("lightblue1"), maxColor("dark blue");
  156.     switch (mode) {
  157.     default:
  158.         break;
  159.     case eDrawObjectLines:
  160.         {{
  161.             CAlignmentSmear::runlen_iterator gap_it = smear.SmearGapBegin();
  162.             for (; gap_it; gap_it.Advance()) {
  163.                 float   value = gap_it.GetValue();
  164.                 if (value == 0)
  165.                     continue;
  166.                 
  167.                 glColor4f(maxColor.GetRed(), maxColor.GetGreen(), maxColor.GetBlue(), 1.0f);
  168.                 TModelUnit f = gap_it.GetSeqPosition();
  169.                 TModelUnit t = f + gap_it.GetSeqRunLength();
  170.                 glVertex2f(f - offsetX, line_ym - offsetY);
  171.                 glVertex2f(t - offsetX, line_ym - offsetY); 
  172.             }               
  173.         }}
  174.         break;
  175.         
  176.     case eDrawObjectQuads:
  177.         {{
  178.             CAlignmentSmear::runlen_iterator seg_it = smear.SmearSegBegin();
  179.             for (; seg_it; seg_it.Advance()) {
  180.                 float   value = seg_it.GetValue();
  181.                 if (value == 0)
  182.                     continue;
  183.                 
  184.                 // set color of segment.
  185.                 float   score = value/smear.GetMaxValue();
  186.                 // CGlColor(1.0f-score, 1.0f-score, 1.0f-score); // shades of grey.
  187.                 // glColor4f(1.0f-score, 1.0f-score, 1.0f-score, 0.65);
  188.                 CRgbaColor color(CRgbaColor::Interpolate(maxColor, minColor, score));
  189.                 glColor4f(color.GetRed(), color.GetGreen(), color.GetBlue(), 1.0f);
  190.                 
  191.                 // draw segment
  192.                 TModelUnit f = seg_it.GetSeqPosition();
  193.                 TModelUnit t = f + seg_it.GetSeqRunLength();
  194.                 glVertex2f(f - offsetX, line_y1 - offsetY);
  195.                 glVertex2f(f - offsetX, line_y2 - offsetY);
  196.                 glVertex2f(t - offsetX, line_y2 - offsetY);
  197.                 glVertex2f(t - offsetX, line_y1 - offsetY);
  198.             } 
  199.         }}
  200.         break;
  201.     case eDrawObjectLabel:
  202.         {{
  203.             string as_label = smear.GetLabel();
  204.       
  205.             if (selected) {
  206.                 x_Color(CSeqGraphicColorConfig::eSelLabel_AlignSmear);
  207.             } else {
  208.                 x_Color(CSeqGraphicColorConfig::eLabel_AlignSmear);
  209.             }
  210.         
  211.             m_Font_Helv10.TextOut(rcV.Left() - offsetX + 3, title_y - off - offsetY, as_label.c_str());
  212.             // draw strand indicator if needed.
  213.             if (smear.GetStrandType() != CAlignmentSmear::eSmearStrand_Both) {
  214.                 bool neg_strand = smear.GetStrandType() == CAlignmentSmear::eSmearStrand_Neg;
  215.             
  216.                 glColor3f(0.0f, 0.0f, 0.0f);  // Black
  217.             
  218.                 m_Font_Helv10.TextOut(rcV.Left() - offsetX + 3, strand_y - off - offsetY, neg_strand ? "<" : ">");
  219.             }
  220.         }}
  221.         break;
  222.     }    
  223. }
  224. void CDefaultPolicy::x_DrawAlignment(CGlPane& pane, const CLayoutAlign* align, 
  225.                     GLfloat row_y, EObj_IterMode mode, bool selected) const
  226. {
  227.     const TModelRect& rcV = pane.GetVisibleRect();
  228.     const CAlnVec& aln_mgr = align->GetAlignMgr();
  229.     TModelUnit offsetX = pane.GetOffsetX();
  230.     TModelUnit offsetY = pane.GetOffsetY();
  231.     TSeqPos from = align->GetLocation().GetTotalRange().GetFrom();
  232.     TSeqPos to   = align->GetLocation().GetTotalRange().GetTo();
  233.     TModelRect frc;
  234.     frc.SetLeft(from);
  235.     frc.SetRight(to);
  236.     TModelRect inrc = frc.IntersectWith(rcV);
  237.     GLfloat scaleX = pane.GetScaleX();
  238.     GLfloat yy  = row_y + m_Font_Helv10.TextHeight() + 4;
  239.     GLfloat aln_height = x_CalcAlignHeight(align);
  240.     switch (mode) {
  241.     default:
  242.         break;
  243.     case eDrawObjectLines:
  244.         {{
  245.             x_Color(CSeqGraphicColorConfig::eFG_Alignment);
  246.             CAlnMap::TNumrow anchor = aln_mgr.GetAnchor();
  247.             TSeqPos start = aln_mgr.GetSeqStart(anchor);
  248.             TSeqPos stop  = aln_mgr.GetSeqStop (anchor);
  249.             CAlnMap::TNumrow row = 0;
  250.             for (row = 0;  row < aln_mgr.GetNumRows();  ++row) {
  251.                 if (row == anchor) {
  252.                     continue;  // skip master seq
  253.                 }
  254.                 glVertex2f(start - offsetX,     yy - offsetY + kAlnElementHeight * 0.5f);
  255.                 glVertex2f(stop  - offsetX + 1, yy - offsetY + kAlnElementHeight * 0.5f);
  256.                 // advance to next row: 1 pixel between
  257.                 yy += kAlnElementHeight + 1;
  258.             }
  259.         }}
  260.         // Draw selection
  261.         if (selected) {
  262.             x_Color(CSeqGraphicColorConfig::eSelection_Alignment);
  263.             x_DrawSelection(pane, from, row_y, to, row_y + aln_height);
  264.         }
  265.         break;
  266.     case eDrawObjectQuads:
  267.         {{
  268.             x_Color(CSeqGraphicColorConfig::eFG_Alignment);
  269.              CAlnMap::TNumrow row = 0;
  270.              const CAlnMap::TNumrow anchor = aln_mgr.GetAnchor();
  271.              TSignedSeqRange range(aln_mgr.GetAlnStart(),
  272.                                    aln_mgr.GetAlnStop());
  273.              for ( ;  row < aln_mgr.GetNumRows();  ++row) {
  274.                  if (row == anchor) {
  275.                      continue;  // skip master seq
  276.                  }
  277.                  CRef<CAlnVec::CAlnChunkVec> aln_chunks
  278.                      (aln_mgr.GetAlnChunks(row, range,
  279.                                            CAlnVec::fSeqOnly |
  280.                                            CAlnVec::fChunkSameAsSeg));
  281.                  for (int i = 0;  i < aln_chunks->size();  ++i) {
  282.                      CConstRef<CAlnVec::CAlnChunk> chunk((*aln_chunks)[i]);
  283.                      TSeqPos start = chunk->GetRange().GetFrom();
  284.                      start = aln_mgr.GetSeqPosFromSeqPos(anchor, row, start);
  285.                      TSeqPos stop = chunk->GetRange().GetTo();
  286.                      stop = aln_mgr.GetSeqPosFromSeqPos(anchor, row, stop);
  287.                      if (start > stop) {
  288.                          swap(start, stop);
  289.                      }
  290.                      glVertex2f(start - offsetX,     yy - offsetY);
  291.                      glVertex2f(stop  - offsetX + 1, yy - offsetY);
  292.                      glVertex2f(stop  - offsetX + 1,
  293.                                 yy + kAlnElementHeight - offsetY);
  294.                      glVertex2f(start - offsetX,
  295.                                 yy + kAlnElementHeight - offsetY);
  296.                  }
  297.                  // advance to next row: 1 pixel between
  298.                  yy += kAlnElementHeight + 1;
  299.              }
  300.         }}
  301.         break;
  302.     case eDrawObjectLabel:
  303.         if (inrc.Width() < pane.UnProjectWidth(m_MinLabelWidth)) {
  304.             break;
  305.         }
  306.         if (selected) {
  307.             x_Color(CSeqGraphicColorConfig::eSelLabel_Alignment);
  308.         } else {
  309.             x_Color(CSeqGraphicColorConfig::eLabel_Alignment);
  310.         }
  311.         {{
  312.             string title;
  313.             string out;
  314.             // title = "alignment label"; // TESTING 
  315.             x_GetTitle(align, &title);
  316.             
  317.             out = m_Font_Helv10.Truncate(title.c_str(), inrc.Width() / scaleX);
  318.             GLfloat xM = x_CenterText(pane, inrc, 
  319.                                       m_Font_Helv10.TextWidth(out.c_str()));
  320.             GLfloat title_y  = row_y + m_Font_Helv10.TextHeight() + 1;
  321.             m_Font_Helv10.TextOut(xM - offsetX, title_y - offsetY, out.c_str());
  322.         }}
  323.         break;
  324.     }
  325. }
  326. void CDefaultPolicy::x_DrawSeqGraph(CGlPane& pane, const CLayoutGraph* graph,
  327.                     GLfloat row_y, EObj_IterMode mode, bool selected) const
  328. {
  329.     const TModelRect& rcV = pane.GetVisibleRect();
  330.     const CMappedGraph& gr = graph->GetGraph();
  331.     const CSeq_graph::C_Graph& gr_data = gr.GetGraph();
  332.     
  333.     TModelUnit offsetX = pane.GetOffsetX();
  334.     TModelUnit offsetY = pane.GetOffsetY();
  335.     TSeqRange range = graph->GetLocation().GetTotalRange();
  336.     TSeqPos from = range.GetFrom();
  337.     TSeqPos to   = range.GetTo();
  338.     
  339.     TModelUnit one_row = x_GetRowHeight(pane, graph, selected);
  340.     TModelRect frc;
  341.     frc.SetLeft(from);
  342.     frc.SetRight(to);
  343.     TModelRect inrc = frc.IntersectWith(rcV);
  344.     GLfloat scaleX = pane.GetScaleX();
  345.     switch (mode) {
  346.     default:
  347.         break;
  348.     case eDrawObjectLines:        
  349.         x_Color(CSeqGraphicColorConfig::eFG_SeqGraph);
  350.         switch (gr_data.Which()) {
  351.         case CSeq_graph::TGraph::e_Byte:
  352.             x_PreparePlot(pane, gr_data.GetByte(), range, row_y, one_row);
  353.             break;
  354.         case CSeq_graph::TGraph::e_Real:
  355.             x_PreparePlot(pane, gr_data.GetReal(), range, row_y, one_row);
  356.             break;
  357.         case CSeq_graph::TGraph::e_Int:
  358.             x_PreparePlot(pane, gr_data.GetInt(), range, row_y, one_row);
  359.             break;
  360.         default:
  361.             return;
  362.         }
  363.         // Draw selection (two rows!)
  364.         if (selected) {
  365.             x_Color(CSeqGraphicColorConfig::eSelection_SeqGraph);
  366.             x_DrawSelection(pane, from, row_y, to, row_y + one_row);
  367.         }
  368.         break;
  369.     case eDrawObjectQuads:
  370.         // blue quad for the graph
  371.         x_Color(CSeqGraphicColorConfig::eBG_SeqGraph);
  372.         x_DrawQuad(pane, from, row_y+1, to + 1, row_y + one_row-2);
  373.         break;
  374.     case eDrawObjectLabel:
  375.         if (gr.IsSetTitle()) {
  376.             if (selected) {
  377.                 x_Color(CSeqGraphicColorConfig::eSelLabel_SeqGraph);
  378.             } else {
  379.                 x_Color(CSeqGraphicColorConfig::eLabel_SeqGraph);
  380.             }
  381.             int min_v = 0, max_v = 0;
  382.             switch (gr_data.Which()) {
  383.             case CSeq_graph::TGraph::e_Byte:
  384.                     min_v = int(gr_data.GetByte().GetMin());
  385.                     max_v = int(gr_data.GetByte().GetMax());
  386.                     break;
  387.                 case CSeq_graph::TGraph::e_Real:
  388.                     min_v = int(gr_data.GetReal().GetMin());
  389.                     max_v = int(gr_data.GetReal().GetMax());
  390.                     break;
  391.                 case CSeq_graph::TGraph::e_Int:
  392.                     min_v = int(gr_data.GetInt().GetMin());
  393.                     max_v = int(gr_data.GetInt().GetMax());
  394.                     break;
  395.             }
  396.             string out;
  397.             string title = gr.GetTitle() + "  Min: " + 
  398.                     NStr::UIntToString(min_v) + " / Max: " + 
  399.                     NStr::UIntToString(max_v);
  400.             out = m_Font_Helv10.Truncate(title.c_str(), inrc.Width() / scaleX);
  401.             GLfloat xM = x_CenterText(pane, inrc, 
  402.                                   m_Font_Helv10.TextWidth(out.c_str()));
  403.             GLfloat title_y  = row_y + m_Font_Helv10.TextHeight() + 1;
  404.             m_Font_Helv10.TextOut(xM - offsetX, title_y - offsetY, out.c_str());
  405.         }
  406.         break;
  407.     }
  408. }
  409. void 
  410. CDefaultPolicy::x_DrawHistogram(CGlPane& pane, const CLayoutHistogram* hist,
  411.                     GLfloat row_y, EObj_IterMode mode, bool selected) const
  412. {
  413.     //if (mode != eDrawObjectLabel) {
  414.     if (mode == eDrawObjectLines) { // that's temporary, until a new EObj_IterMode model be ready
  415.         const TVPRect&    rcP = pane.GetViewport();
  416.         const TModelRect& rcV = pane.GetVisibleRect();
  417.         
  418.         glEnd();
  419.         
  420.         pane.Close();
  421.         pane.OpenPixels();
  422.     
  423.         CGlColor color = m_ConfigSettings->GetColor(hist->Which(), 
  424.                                                     hist->Subtype());
  425.         glColor4f(color.GetRed(), color.GetGreen(), color.GetBlue(), 0.65f);
  426.         
  427.         GLfloat one_row = x_GetRowHeight(pane, hist, selected);
  428.         GLfloat height = one_row - 2;  // two pixels space
  429.         GLfloat yy2    = rcV.Bottom() + rcP.Bottom() - one_row - row_y + 1;
  430.         
  431.         glBegin(GL_LINES);
  432.             glVertex2f(rcP.Left(),  yy2);
  433.             glVertex2f(rcP.Right(), yy2);
  434.         glEnd();
  435.     
  436.         TSeqPos x = 0;
  437.         const CDensityMap<int>& densityMap = hist->GetDensityMap();
  438.         GLfloat max_val = densityMap.GetMax();
  439.         
  440.         glBegin(GL_QUAD_STRIP);
  441.         ITERATE(CDensityMap<int>, dens_it, densityMap) {
  442.             GLfloat xx = x;
  443.             GLfloat yy1 = yy2 + height * (*dens_it) / max_val;
  444.             glVertex2f(xx, yy1);
  445.             glVertex2f(xx, yy2);
  446.             ++x;
  447.         }
  448.         glEnd();
  449.         
  450.         pane.Close();
  451.         pane.OpenOrtho();
  452.         glBegin(GL_LINES);
  453.     }
  454. }
  455. void 
  456. CDefaultPolicy::x_DrawSeqSegment(CGlPane& pane, const CLayoutSeqMap* seg,
  457.                     GLfloat row_y, EObj_IterMode mode, bool selected) const
  458. {
  459.     TSeqPos from = seg->GetLocation().GetTotalRange().GetFrom();
  460.     TSeqPos to   = seg->GetLocation().GetTotalRange().GetTo();
  461.     TSeqPos rfrom = seg->GetRefLocation().GetTotalRange().GetFrom();
  462.     TSeqPos rto   = seg->GetRefLocation().GetTotalRange().GetTo();
  463.     GLfloat one_row = x_GetRowHeight(pane, seg, selected);
  464.     GLfloat line_y1  = row_y + 1;
  465.     GLfloat line_y2  = line_y1 + one_row - 2;
  466.     switch (mode) {
  467.     default:
  468.         break;
  469.     case eDrawObjectLines:
  470.         // Draw selection
  471.         if (selected) {
  472.             x_Color(CSeqGraphicColorConfig::eSelection_SeqSegment);
  473.             x_DrawSelection(pane, from, line_y1, to, line_y2);
  474.         }
  475.         break;
  476.     case eDrawObjectQuads:
  477.         x_Color(CSeqGraphicColorConfig::eFG_SeqSegmentExc);
  478.         x_DrawQuad(pane, from, line_y1, to, line_y2);
  479.         x_Color(CSeqGraphicColorConfig::eFG_SeqSegmentInc);        
  480.         x_DrawQuad(pane, rfrom, line_y1, rto, line_y2);
  481.         break;
  482.     case eDrawObjectLabel:
  483.         break;
  484.     }
  485. }
  486. void 
  487. CDefaultPolicy::x_DrawSequence(CGlPane& pane, const CLayoutSequence* seqs,
  488.                     GLfloat row_y, EObj_IterMode mode, bool selected) const
  489. {
  490.     const TModelRect& rcV = pane.GetVisibleRect();
  491.     //const TModelRect& rcM = pane.GetModelLimitsRect();
  492.     
  493.     TModelUnit offsetX = pane.GetOffsetX();
  494.     TModelUnit offsetY = pane.GetOffsetY();
  495.     TModelUnit left  = rcV.Left() - offsetX;
  496.     TModelUnit right = rcV.Right() - offsetX + 1;
  497.     TModelUnit top    = row_y - offsetY;
  498.     TModelUnit bottom = row_y + 16 - offsetY;
  499.     
  500.     switch (mode) {
  501.     default:
  502.         break;
  503.     case eDrawObjectLines:
  504.         break;
  505.     case eDrawObjectQuads:
  506.         glColor3f(0.05f, 0.05f, 0.05f);
  507.         glVertex2f(left,  top);
  508.         glVertex2f(right, top);
  509.         glVertex2f(right, bottom);
  510.         glVertex2f(left,  bottom);
  511.     
  512.         glColor3f(0.5f, 0.5f, 0.5f);
  513.         glVertex2f(left,  top + 1);
  514.         glVertex2f(right, top + 1);
  515.         glVertex2f(right, bottom - 1);
  516.         glVertex2f(left,  bottom - 1);
  517.         break;
  518.     case eDrawObjectLabel:
  519.         {{
  520.             GLfloat y = row_y + m_Font_Bitmap9x15.TextHeight() + 2 - offsetY;
  521.             string seq = seqs->GetSequence();
  522.             GLfloat x = TSeqPos(rcV.Left()) - offsetX + 0.5;
  523.             x_Color(CSeqGraphicColorConfig::eSeq_SequenceBar);
  524.             m_Font_Bitmap9x15
  525.                 .ArrayTextOut(x, y, 1.0f, 0.0f, seq.c_str(), 
  526.                               (float) pane.GetScaleX(), 0.0f);
  527.         }}
  528.         break;
  529.     }
  530. }
  531. void 
  532. CDefaultPolicy::x_DrawComments(CGlPane& pane, const CLayoutComment* comm,
  533.                     GLfloat row_y, EObj_IterMode mode, bool selected) const
  534. {
  535.     const TModelRect& rcV = pane.GetVisibleRect();
  536.     
  537.     TModelUnit offsetX = pane.GetOffsetX();
  538.     TModelUnit offsetY = pane.GetOffsetY();
  539.     
  540.     GLfloat th = m_Font_Helv10.TextHeight();
  541.     GLfloat title_y = row_y + th + 1;
  542.     GLfloat off     = pane.GetModelLimitsRect().Top() > 0 ? th - 1 : 0;
  543.     switch (mode) {
  544.     default:
  545.         break;
  546.     case eDrawObjectLines:
  547.     case eDrawObjectQuads:
  548.         break;
  549.     case eDrawObjectLabel:
  550.         const string& out = comm->GetComment();
  551.         x_Color(CSeqGraphicColorConfig::eFG_Comment);
  552.         m_Font_Helv10.TextOut(rcV.Left() - offsetX, title_y - off - offsetY, out.c_str());
  553.         break;
  554.     }
  555. }
  556. void CDefaultPolicy::x_DrawMatePair(CGlPane& pane, const CLayoutMatePair* pr,
  557.                     GLfloat row_y, EObj_IterMode mode, bool selected) const
  558. {
  559.     const TModelRect& rcV = pane.GetVisibleRect();
  560.     // It's a vector of CRefs
  561.     const CLayoutMatePair::TAlignList& pw_aligns = pr->GetSeqAligns();
  562.     TModelUnit offsetX = pane.GetOffsetX();
  563.     TModelUnit offsetY = pane.GetOffsetY();
  564.     TSeqPos from = pr->GetLocation().GetTotalRange().GetFrom();
  565.     TSeqPos to   = pr->GetLocation().GetTotalRange().GetTo();
  566.     TModelRect frc;
  567.     frc.SetLeft(from);
  568.     frc.SetRight(to);
  569.     TModelRect inrc = frc.IntersectWith(rcV);
  570.     GLfloat scaleX = pane.GetScaleX();
  571.     GLfloat yy;
  572.     if (m_ConfigSettings->GetShowPWAlignLabels()) {
  573.         yy = row_y + m_Font_Helv10.TextHeight() + 4;
  574.     } else {
  575.         yy = row_y + 2;
  576.     }
  577.     
  578.     // Set Colors based on Error code for Mate Pairs
  579.     CSeqGraphicColorConfig::EDisplayElement c_fg, c_seq, c_mis;
  580.     switch (pr->GetError()) {
  581.         case CLayoutMatePair::eError_Orientation:
  582.             c_fg  = CSeqGraphicColorConfig::eFG_MatePairOrientation;
  583.             c_seq = CSeqGraphicColorConfig::eSeq_MatePairOrientation;
  584.             c_mis = CSeqGraphicColorConfig::eSeq_MatePairMismatchOrientation;
  585.             break;
  586.         case CLayoutMatePair::eError_NonUnique:
  587.             c_fg  = CSeqGraphicColorConfig::eFG_MatePairNonUnique;
  588.             c_seq = CSeqGraphicColorConfig::eSeq_MatePairNonUnique;
  589.             c_mis = CSeqGraphicColorConfig::eSeq_MatePairMismatchNonUnique;
  590.             break;
  591.         case CLayoutMatePair::eError_Distance:
  592.             c_fg  = CSeqGraphicColorConfig::eFG_MatePairDistance;
  593.             c_seq = CSeqGraphicColorConfig::eSeq_MatePairDistance;
  594.             c_mis = CSeqGraphicColorConfig::eSeq_MatePairMismatchDistance;
  595.             break;
  596.         default:
  597.             c_fg  = CSeqGraphicColorConfig::eFG_MatePairNo;
  598.             c_seq = CSeqGraphicColorConfig::eSeq_MatePairNo;
  599.             c_mis = CSeqGraphicColorConfig::eSeq_MatePairMismatchNo;            
  600.             break;
  601.     }
  602.     
  603.     switch (mode) {
  604.     default:
  605.         break;
  606.     case eDrawObjectLines:
  607.         // Draw each Pairwise  Alignment inside  
  608.         ITERATE(CLayoutMatePair::TAlignList, iter, pw_aligns) {
  609.             bool has_sel  = selected ? pr->IsSelected(iter->GetPointer()) :
  610.                             selected;
  611.             x_DrawPWAlignElem(pane, iter->GetPointer(), row_y, mode, 
  612.                               has_sel, c_fg, c_seq, c_mis);
  613.         }
  614.         // draw link between mate pairs
  615.         x_Color(CSeqGraphicColorConfig::eFG_MatePairLink);
  616.         for(size_t i = 0;  i != pw_aligns.size() - 1;  i++) {
  617.             TSeqRange r1 = pw_aligns[i]->GetLocation().GetTotalRange();
  618.             TSeqRange r2 = pw_aligns[i+1]->GetLocation().GetTotalRange();
  619.             TSeqPos from = r1.GetTo() < r2.GetFrom() ? 
  620.                            r1.GetTo() : r2.GetTo();
  621.             TSeqPos to   = r1.GetTo() < r2.GetFrom() ? 
  622.                            r2.GetFrom() : r1.GetFrom();
  623.             
  624.             glVertex2f(from - offsetX + 1, yy - offsetY + 
  625.                             kPWAlignHeight * 0.5f);
  626.             glVertex2f(to   - offsetX, yy - offsetY + 
  627.                             kPWAlignHeight * 0.5f);
  628.         }
  629.         break;
  630.     case eDrawObjectQuads:
  631.         // Highlight background based on Library ID
  632.         if (pr->GetLibraryId() > 0) {
  633.             CGlColor color = m_ColorTable.GetColor(pr->GetLibraryId());
  634.             glColor4f(color.GetRed(), color.GetGreen(), color.GetBlue(), 0.1f);
  635.             TModelUnit h = x_GetRowHeight(pane, pr, selected);
  636.             x_DrawQuad(pane, from, row_y, to, row_y + h);            
  637.         }
  638.     case eDrawObjectLabel:
  639.         if (mode == eDrawObjectLabel  &&    
  640.             inrc.Width() > pane.UnProjectWidth(m_MinLabelWidth) &&
  641.             m_ConfigSettings->GetShowPWAlignLabels() ) {
  642.             string title;
  643.             x_GetTitle(pr, &title);
  644.             
  645.             string out = m_Font_Helv10.Truncate(title.c_str(),  
  646.                                 inrc.Width() / scaleX);
  647.             GLfloat xM = x_CenterText(pane, inrc, 
  648.                                 m_Font_Helv10.TextWidth(out.c_str()));
  649.             x_Color(selected ? CSeqGraphicColorConfig::eSelLabel_MatePair :
  650.                                CSeqGraphicColorConfig::eLabel_MatePair);
  651.             GLfloat title_y  = row_y + m_Font_Helv10.TextHeight() + 1;
  652.             m_Font_Helv10.TextOut(xM - offsetX, title_y - offsetY, out.c_str());
  653.         }
  654.         
  655.         ITERATE(CLayoutMatePair::TAlignList, iter, pw_aligns) {
  656.             x_DrawPWAlignElem(pane, iter->GetPointer(), row_y, mode,
  657.                             selected, c_fg, c_seq, c_mis);
  658.         }
  659.         break;
  660.     } 
  661. }
  662. // Placeholder. Used in genome-scale view
  663. void 
  664. CDefaultPolicy::x_DrawFeatPack(CGlPane&, const CLayoutFeatPack*,
  665.                     GLfloat, EObj_IterMode, bool) const
  666. {
  667. }
  668. void 
  669. CDefaultPolicy::x_DrawFeatLabel(CGlPane& pane, const CLayoutFeatLabel* feat, 
  670.                     GLfloat row_y, EObj_IterMode mode, bool selected) const
  671. {
  672.     const TModelRect& rcV = pane.GetVisibleRect();
  673.     const TModelRect& rcM = pane.GetModelLimitsRect();
  674.     
  675.     TModelUnit offsetX = pane.GetOffsetX();
  676.     TModelUnit offsetY = pane.GetOffsetY();
  677.     
  678.     GLfloat th = m_Font_Helv10.TextHeight();
  679.     GLfloat title_y  = row_y + th + 1;
  680.     GLfloat off      = rcM.Top() > 0 ? th - 1 : 0;
  681.     switch (mode) {
  682.     default:
  683.     case eDrawObjectLines:
  684.     case eDrawObjectQuads:
  685.         break;
  686.     case eDrawObjectLabel:
  687.         string content;        
  688.         feature::GetLabel(feat->GetFeature(), &content, 
  689.                           feature::eContent, &m_Handle.GetScope());
  690.         if (selected) 
  691.             x_Color(CSeqGraphicColorConfig::eSelLabel_Feature);
  692.         else
  693.             x_Color(CSeqGraphicColorConfig::eLabel_Feature);
  694.         TModelUnit col_width  = pane.UnProjectWidth(kLabelsColWidth);
  695.         
  696.         TModelUnit col_offset = col_width * feat->GetColumn();
  697.         // Trim label to fit in kLabelsColWidth
  698.         string out;
  699.         out = m_Font_Helv10.Truncate(content.c_str(), kLabelsMaxWidth);
  700.             
  701.         m_Font_Helv10.TextOut(rcV.Left() - offsetX + col_offset, 
  702.                               title_y - off - offsetY, out.c_str());
  703.         break;
  704.     }
  705. }
  706. //
  707. // draw a given feature in a given mode
  708. //
  709. void 
  710. CDefaultPolicy::x_DrawFeature(CGlPane& pane, const CLayoutFeat* feat, 
  711.                 GLfloat row_y, EObj_IterMode mode, bool selected) const
  712. {
  713.     const TModelRect& rcV = pane.GetVisibleRect();
  714.     const TModelRect& rcM = pane.GetModelLimitsRect();
  715.     
  716.     TModelUnit offsetX = pane.GetOffsetX();
  717.     TModelUnit offsetY = pane.GetOffsetY();
  718.     
  719.     TSeqPos from = feat->GetLocation().GetTotalRange().GetFrom();
  720.     TSeqPos to   = feat->GetLocation().GetTotalRange().GetTo();
  721.     TModelRect frc;
  722.     frc.SetLeft(from);
  723.     frc.SetRight(to);    
  724.     TModelRect inrc = frc.IntersectWith(rcV);
  725.     GLfloat scaleX  = pane.GetScaleX();
  726.     GLfloat th = m_Font_Helv10.TextHeight();
  727.     GLfloat title_y  = row_y + th + 1;
  728.     GLfloat line_y1  = title_y + 3;
  729.     GLfloat line_y2  = line_y1 + th + 2;
  730.     GLfloat line_ym  = line_y1 + (th + 2) / 2;
  731.     GLfloat strand_y = line_y1 + th;
  732.     GLfloat off      = rcM.Top() > 0 ? th - 1 : 0;
  733.     
  734.     bool neg_strand = (sequence::GetStrand(feat->GetLocation()) 
  735.                             == eNa_strand_minus);
  736.     switch (mode) {
  737.     default:
  738.         break;
  739.     case eDrawObjectLines:
  740.         x_SetFeatureColor(feat);
  741.         if (true/*kShowIntrons*/) {  // ^ line
  742.             GLfloat prev_to_x = 0.0f;
  743.             bool first_pass = true;
  744.             ITERATE (vector<TSeqRange>, iter, feat->GetIntervals()) {
  745.                 const TSeqRange& curr = *iter;
  746.                 TModelUnit from_x, to_x;
  747.                 if (neg_strand) {
  748.                     from_x = curr.GetTo()+1;
  749.                     to_x   = curr.GetFrom();
  750.                 } else {
  751.                     from_x = curr.GetFrom();
  752.                     to_x   = curr.GetTo()+1;
  753.                 }
  754.                 if (!first_pass) {
  755.                     GLfloat middle_x = prev_to_x + (from_x - prev_to_x) / 2.0f;
  756.                     glVertex2f(prev_to_x - offsetX, line_ym - offsetY);
  757.                     glVertex2f(middle_x - offsetX,  line_y1 - offsetY);
  758.                     glVertex2f(middle_x - offsetX,  line_y1 - offsetY);
  759.                     glVertex2f(from_x - offsetX,    line_ym - offsetY);
  760.                 }
  761.                 prev_to_x  = to_x;
  762.                 first_pass = false;
  763.             }
  764.         } else {  // straight line
  765.             glVertex2f(from - offsetX, line_ym - offsetY);
  766.             glVertex2f(to - offsetX,   line_ym - offsetY);
  767.         }
  768.         // Draw selection
  769.         if (selected) {
  770.             x_Color(CSeqGraphicColorConfig::eSelection_Feature);
  771.             x_DrawSelection(pane, from, line_y1, to, line_y2);
  772.         }
  773.         break;
  774.     case eDrawObjectQuads:
  775.         // Highlight named Seq Annotations
  776.         if (feat->GetMappedFeature().GetAnnot().IsNamed()) {
  777.             CSeq_annot_Handle annot = feat->GetMappedFeature().GetAnnot();
  778.             size_t idx = x_GetSeqAnnotIndex(annot);
  779.             
  780.             TModelUnit h = x_GetRowHeight(pane, feat, selected);// * kOneRowHeight;
  781.             CGlColor color = m_ColorTable.GetColor(idx);
  782.             glColor4f(color.GetRed(), color.GetGreen(), color.GetBlue(), 0.1f);
  783.             
  784.             // add small overhang of 5 pixels (left and right)
  785.             TModelUnit over = pane.UnProjectWidth(5);
  786.             x_DrawQuad(pane, from - over, row_y, to + over + 1, row_y + h);
  787.         }
  788.         x_SetFeatureColor(feat);
  789.         
  790.         // quad for each interval (exon)
  791.         ITERATE (vector<TSeqRange>, iter, feat->GetIntervals()) {
  792.             const TSeqRange& curr = *iter;
  793.             TModelUnit f = curr.GetFrom();
  794.             TModelUnit t = curr.GetTo()+1;// + (neg_strand ? 0.0f : 1.0f);
  795.             
  796.             if (pane.ProjectX(t) - pane.ProjectX(f) <= 1.0f) {
  797.                 t = f + pane.UnProjectWidth(1);
  798.             }
  799.             x_DrawQuad(pane, f, line_y1, t, line_y2);
  800.         }
  801.         
  802.         break;
  803.     case eDrawObjectLabel:
  804.         // do not even try to draw labels if less than 1 letter width
  805.         if (inrc.Width() <= pane.UnProjectWidth(m_MinLabelWidth)) {
  806.             break;
  807.         }
  808.         string fl_both;
  809.         string fl_type;
  810.         string fl_content;
  811.         string fl_out;
  812.         x_GetLabels(feat->GetFeature(), m_Handle.GetScope(),
  813.                     &fl_type, &fl_content, &fl_both);
  814.         GLfloat widthP     = inrc.Width() / scaleX; // width in pixels
  815.         GLfloat lw_type    = m_Font_Helv10.TextWidth(fl_type.c_str() );
  816.         if ( lw_type * 3 < widthP) { // 3 widths of eType label width
  817.             fl_out = m_Font_Helv10.Truncate(fl_both.c_str(), widthP);
  818.         } else {
  819.             fl_out = m_Font_Helv10.Truncate(fl_content.c_str(), widthP);
  820.         }
  821.         
  822.         if (selected) {
  823.             x_Color(CSeqGraphicColorConfig::eSelLabel_Feature);
  824.         } else {
  825.             x_Color(CSeqGraphicColorConfig::eLabel_Feature);
  826.         }
  827.         
  828.         GLfloat xM = x_CenterText(pane, inrc, 
  829.                      m_Font_Helv10.TextWidth(fl_out.c_str()));
  830.         m_Font_Helv10.TextOut(xM - offsetX, title_y - off - offsetY, fl_out.c_str());
  831.         // draw strand indicator
  832.         xM = x_CenterText(pane, inrc, m_Font_Helv10.TextWidth("<"));
  833.         glColor3f(0.0f, 0.0f, 0.0f);  // strand Black
  834.         
  835.         m_Font_Helv10.TextOut(xM - offsetX, strand_y - off - offsetY, neg_strand ? "<" : ">");
  836.         break;
  837.     }
  838. }
  839. void CDefaultPolicy::x_DrawPWAlignElem(CGlPane& pane, const CLayoutPWAlign* pw_aln,
  840.                     GLfloat row_y, EObj_IterMode mode, bool selected,
  841.                     CSeqGraphicColorConfig::EDisplayElement c_fg, 
  842.                     CSeqGraphicColorConfig::EDisplayElement c_seq,
  843.                     CSeqGraphicColorConfig::EDisplayElement c_mis) const
  844. {
  845.     const CAlnVec& aln_mgr = pw_aln->GetAlignMgr();
  846.     CAlnMap::TNumrow anchor = aln_mgr.GetAnchor();
  847.     TSignedSeqRange range(aln_mgr.GetAlnStart(), aln_mgr.GetAlnStop());
  848.     TSeqPos from = pw_aln->GetLocation().GetTotalRange().GetFrom();
  849.     TSeqPos to   = pw_aln->GetLocation().GetTotalRange().GetTo();
  850.     TModelUnit offsetX = pane.GetOffsetX();
  851.     TModelUnit offsetY = pane.GetOffsetY();
  852.     const TModelRect& rcV = pane.GetVisibleRect();
  853.     
  854.     TModelRect frc;
  855.     frc.SetLeft(from);
  856.     frc.SetRight(to);    
  857.     TModelRect inrc = frc.IntersectWith(rcV);
  858.     GLfloat yy;
  859.     if (m_ConfigSettings->GetShowPWAlignLabels()) {
  860.         yy = row_y + m_Font_Helv10.TextHeight() + 4;
  861.     } else {
  862.         yy = row_y + 2;
  863.     }
  864.     
  865.     GLfloat height = x_GetRowHeight(pane, pw_aln, selected);
  866.     GLfloat scaleX = pane.GetScaleX();
  867.     CAlnMap::TNumrow row = 0;
  868.     bool neg_strand = aln_mgr.IsNegativeStrand(anchor == 0 ? 1 : 0);
  869.     
  870.     switch (mode) {
  871.     default:
  872.         break;
  873.     case eDrawObjectLines: {
  874.         TSeqPos f = aln_mgr.GetSeqStart(anchor);
  875.         TSeqPos t = aln_mgr.GetSeqStop(anchor);
  876.         x_Color(c_fg);
  877.         if (scaleX < 2) {
  878.             TModelUnit over8 = pane.UnProjectWidth(7);
  879.             TModelUnit over2 = pane.UnProjectWidth(2);
  880.             
  881.             if (neg_strand) {
  882.                 glVertex2f(f - offsetX - over2, yy - offsetY + kPWAlignHeight * 0.5f);
  883.                 glVertex2f(t - offsetX + 1, yy - offsetY + kPWAlignHeight * 0.5f);                
  884.             } else {
  885.                 glVertex2f(f - offsetX, yy - offsetY + kPWAlignHeight * 0.5f);
  886.                 glVertex2f(t - offsetX + over2 + 1, yy - offsetY + kPWAlignHeight * 0.5f);
  887.             }
  888.             glEnd();
  889.             glBegin(GL_TRIANGLES);
  890.             if (neg_strand) {
  891.                 glVertex2f(f - offsetX - over8, yy - offsetY + kPWAlignHeight * 0.5f);
  892.                 glVertex2f(f - offsetX - over2, yy - offsetY - 1);
  893.                 glVertex2f(f - offsetX - over2, yy - offsetY + kPWAlignHeight + 1);
  894.             } else {
  895.                 glVertex2f(t - offsetX + 1 + over8, yy - offsetY + kPWAlignHeight * 0.5f);
  896.                 glVertex2f(t - offsetX + 1 + over2, yy - offsetY - 1);
  897.                 glVertex2f(t - offsetX + 1 + over2, yy - offsetY + kPWAlignHeight + 1);
  898.             }
  899.             glEnd();    
  900.             glBegin(GL_LINES);
  901.         }
  902.         else {
  903.             glVertex2f(f - offsetX, yy - offsetY + kPWAlignHeight * 0.5f);
  904.             glVertex2f(t - offsetX + 1, yy - offsetY + kPWAlignHeight * 0.5f);
  905.         }
  906.         }
  907.         // Draw selection
  908.         if (selected) {
  909.             x_Color(CSeqGraphicColorConfig::eSelection_PWAlign);
  910.             x_DrawSelection(pane, from, row_y, to, row_y + height);
  911.         }
  912.         break;
  913.     case eDrawObjectQuads:
  914.     case eDrawObjectLabel:
  915.         // Draw Strand Indicator (do not draw labels if less than 1 letter width)
  916.         // do not draw strand when sequence is shown
  917.         if (mode == eDrawObjectLabel  &&  
  918.                 inrc.Width() > pane.UnProjectWidth(m_MinLabelWidth) &&
  919.                 scaleX > 1.0f / 6.0f) {
  920.             GLfloat xM = x_CenterText(pane, inrc, m_Font_Helv10.TextWidth("<"));
  921.             glColor3f(0.0f, 0.0f, 0.0f);  // Black
  922.             m_Font_Helv10.TextOut(xM - offsetX, yy + 
  923.                             m_Font_Helv10.TextHeight() - offsetY - 2, 
  924.                             neg_strand ? "<" : ">");
  925.         }
  926.         
  927.         // Should we draw sequence?
  928.         if (mode == eDrawObjectLabel  &&  scaleX > 1.0f / 6.0f) {
  929.             return;  // sequence would not fit
  930.         }
  931.         
  932.         // Draw Sequence and quads for segments
  933.         for ( ;  row < aln_mgr.GetNumRows();  ++row) {
  934.             if (row == anchor) {
  935.                 continue;  // skip master seq
  936.             }
  937.             CRef<CAlnVec::CAlnChunkVec> aln_chunks
  938.                 (aln_mgr.GetAlnChunks(row, range,
  939.                                       CAlnVec::fSeqOnly |
  940.                                       CAlnVec::fChunkSameAsSeg));
  941.             
  942.             for (int i = 0;  i < aln_chunks->size();  ++i) {
  943.                 CConstRef<CAlnVec::CAlnChunk> chunk((*aln_chunks)[i]);
  944.                 TSeqPos start = chunk->GetRange().GetFrom();
  945.                 start = aln_mgr.GetSeqPosFromSeqPos(anchor, row, start);
  946.                 TSeqPos stop = chunk->GetRange().GetTo();
  947.                 stop = aln_mgr.GetSeqPosFromSeqPos(anchor, row, stop);
  948.                 if (start > stop) {
  949.                     swap(start, stop);
  950.                 }
  951.                 if (mode == eDrawObjectQuads) {
  952.                     x_Color(c_fg);
  953.                     x_DrawQuad(pane, start, yy, stop, yy + kPWAlignHeight);
  954.                 } else if (mode == eDrawObjectLabel) {
  955.                     const CBioseq_Handle& mhndl = aln_mgr.GetBioseqHandle(anchor);
  956.                     const CBioseq_Handle& hndl  = aln_mgr.GetBioseqHandle(row);
  957.                     
  958.                     CSeqVector ms_vec = mhndl.GetSeqVector(
  959.                                         CBioseq_Handle::eCoding_Iupac);
  960.                     CSeqVector s_vec  =  hndl.GetSeqVector(
  961.                                         CBioseq_Handle::eCoding_Iupac);
  962.                                         
  963.                     string seq, mseq, tmp_seq;
  964.                     s_vec.GetSeqData (chunk->GetRange().GetFrom(), 
  965.                                       chunk->GetRange().GetTo() + 1, tmp_seq);
  966.                     ms_vec.GetSeqData(start, stop + 1, mseq);
  967.                     
  968.                     if (neg_strand) {  // reverse&compiment sequence for negative strand
  969.                         CSeqManip::ReverseComplement(tmp_seq, CSeqUtil::e_Iupacna,
  970.                                    0, tmp_seq.length(), seq);
  971.                     } else {
  972.                         seq = tmp_seq;
  973.                     }
  974.                     
  975.                     GLfloat y = yy + m_Font_Helv8.TextHeight() - 1 - offsetY;
  976.                     char bases[2];
  977.                     bases[1] = '';
  978.                     for (TSeqPos bp = 0;  bp != seq.length();  bp++) {
  979.                         if (seq[bp] != mseq[bp]) {  // Highlight mismatch
  980.                             x_Color(c_mis);
  981.                         } else {
  982.                             x_Color(c_seq);
  983.                         }
  984.                         
  985.                         bases[0] = seq[bp];
  986.                         m_Font_Helv8.ArrayTextOut(start - offsetX + bp + 0.5, y, 1.0f, 0.0f, 
  987.                             bases, (float) pane.GetScaleX(), 0.0f);
  988.                     }
  989.                 }
  990.             }
  991.         }
  992.         break;
  993.     }    
  994. }
  995. void CDefaultPolicy::x_DrawPWAlign(CGlPane& pane, const CLayoutPWAlign* pw_aln,
  996.                     GLfloat row_y, EObj_IterMode mode, bool selected) const
  997. {
  998.     const TModelRect& rcV = pane.GetVisibleRect();
  999.     TModelUnit offsetX = pane.GetOffsetX();
  1000.     TModelUnit offsetY = pane.GetOffsetY();
  1001.     TSeqPos from = pw_aln->GetLocation().GetTotalRange().GetFrom();
  1002.     TSeqPos to   = pw_aln->GetLocation().GetTotalRange().GetTo();
  1003.     TModelRect frc;
  1004.     frc.SetLeft(from);
  1005.     frc.SetRight(to);
  1006.     TModelRect inrc = frc.IntersectWith(rcV);
  1007.     GLfloat scaleX = pane.GetScaleX();
  1008.     if (mode == eDrawObjectLabel  &&    
  1009.             inrc.Width() > pane.UnProjectWidth(m_MinLabelWidth)  &&
  1010.             m_ConfigSettings->GetShowPWAlignLabels() ) {
  1011.         string title;
  1012.         x_GetTitle(pw_aln, &title);
  1013.         
  1014.         string out = m_Font_Helv10.Truncate(title.c_str(), 
  1015.                                     inrc.Width() / scaleX);
  1016.         
  1017.         GLfloat xM = x_CenterText(pane, inrc, 
  1018.                             m_Font_Helv10.TextWidth(out.c_str()));
  1019.         x_Color(selected ? CSeqGraphicColorConfig::eSelLabel_PWAlign :
  1020.                            CSeqGraphicColorConfig::eLabel_PWAlign);
  1021.         GLfloat title_y  = row_y + m_Font_Helv10.TextHeight() + 1;
  1022.         m_Font_Helv10.TextOut(xM - offsetX, title_y - offsetY, out.c_str());
  1023.         
  1024.         if (scaleX > 1.0f / 6.0f) { 
  1025.             return;  // sequence would not fit
  1026.         }
  1027.     }
  1028.     
  1029.     x_DrawPWAlignElem(pane, pw_aln, row_y, mode, selected,
  1030.             CSeqGraphicColorConfig::eFG_PWAlign,
  1031.             CSeqGraphicColorConfig::eSeq_PWAlign,
  1032.             CSeqGraphicColorConfig::eSeq_PWAlignMismatch);
  1033. }
  1034. // This is exactly as it done in Sequin.
  1035. TSeqPos CDefaultPolicy::x_GetProtOffset(const CLayoutFeat* feat) const
  1036. {
  1037.     TSeqPos offset = 1; // translation offset
  1038.     const CCdregion& cdr = feat->GetFeature().GetData().GetCdregion();
  1039.     if (cdr.IsSetFrame ()) {
  1040.         switch (cdr.GetFrame ()) {
  1041.         case CCdregion::eFrame_two :
  1042.             offset = 2;
  1043.             break;
  1044.         case CCdregion::eFrame_three :
  1045.             offset = 3;
  1046.             break;
  1047.         default :
  1048.             break;
  1049.         }
  1050.     }
  1051.     return offset;
  1052. }
  1053. void 
  1054. CDefaultPolicy::x_DrawProteinProduct(CGlPane& pane, const CLayoutFeat* feat,
  1055.                     GLfloat row_y, EProtSeqType type, bool selected) const
  1056. {
  1057.     const TModelRect& rcV = pane.GetVisibleRect();
  1058.     const TModelRect& rcM = pane.GetModelLimitsRect();
  1059.     
  1060.     TModelUnit offsetX = pane.GetOffsetX();
  1061.     TModelUnit offsetY = pane.GetOffsetY();
  1062.     
  1063.     TSeqPos from = feat->GetLocation().GetTotalRange().GetFrom();
  1064.     TSeqPos to   = feat->GetLocation().GetTotalRange().GetTo();
  1065.     TModelRect frc;
  1066.     frc.SetLeft(from);
  1067.     frc.SetRight(to);
  1068.     TModelRect inrc = frc.IntersectWith(rcV);
  1069.     // do not do anything if there is no spac for even one letter
  1070.     if (inrc.Width() < pane.UnProjectWidth(m_MinLabelWidth)) {
  1071.         return;
  1072.     }
  1073.     GLfloat scaleX = pane.GetScaleX();    
  1074.     GLfloat th      = m_Font_Helv10.TextHeight();
  1075.     GLfloat title_y = row_y + th + 1;
  1076.     GLfloat line_y1 = title_y + 3;
  1077.     GLfloat bases_y = line_y1 + th;
  1078.     GLfloat off     = rcM.Top() > 0 ? th - 1 : 0;
  1079.     TSeqPos offset = x_GetProtOffset(feat); // initial translation offset
  1080.     // label for original protein only and when product is accessible
  1081.     if (type != eTranslatedSeq  &&  feat->GetFeature().IsSetProduct()) {
  1082.         const CSeq_loc& product = feat->GetFeature().GetProduct();
  1083.         string prot_label;
  1084.         CLabel::GetLabel(product, &prot_label,
  1085.                          CLabel::eDefault, &m_Handle.GetScope());
  1086.         string out = m_Font_Helv10.Truncate(prot_label.c_str(),
  1087.                                             inrc.Width() / scaleX);
  1088.         GLfloat xM = x_CenterText(pane, inrc, m_Font_Helv10.TextWidth(out.c_str()));
  1089.         //x_SetFeatureColor(feat);
  1090.         //x_Color(CSeqGraphicColorConfig::eSeq_ProtTranslated); // eSeq_ProtOriginal?
  1091.         if (selected) {
  1092.             x_Color(CSeqGraphicColorConfig::eSelLabel_ProtProduct);
  1093.         } else {
  1094.             x_Color(CSeqGraphicColorConfig::eLabel_ProtProduct);
  1095.         }
  1096.         m_Font_Helv10.TextOut(xM - offsetX, title_y - off - offsetY, out.c_str());
  1097.     }
  1098.     // // draw actual prot sequence if at the right zoom level
  1099.     if (x_IsSeqLettersFit(pane)) {  
  1100.         string prot_seq, trans_seq;
  1101.         CSeqVector vec = m_Handle.GetSeqVector(CBioseq_Handle::eCoding_Iupac);
  1102.         const CCdregion& cdr = feat->GetFeature().GetData().GetCdregion();        
  1103.         CCdregion_translate::TranslateCdregion(trans_seq, m_Handle,
  1104.                                                feat->GetLocation(),
  1105.                                                cdr, true, true);
  1106.         if (feat->GetFeature().IsSetProduct()) {
  1107.             const CSeq_loc& product = feat->GetFeature().GetProduct();
  1108.             CSeqVector prot_vec =
  1109.                 m_Handle.GetSequenceView(product,
  1110.                                          CBioseq_Handle::eViewConstructed);
  1111.             prot_vec.SetCoding(CBioseq_Handle::eCoding_Iupac);
  1112.             prot_vec.GetSeqData (0, prot_vec.size(), prot_seq);
  1113.         } else {
  1114.             prot_seq = trans_seq;
  1115.         }
  1116.         TSeqPos seq_start;
  1117.         size_t idx = 0;
  1118.         for (CSeq_loc_CI lit(feat->GetLocation()); lit; ++lit) {
  1119.             TSeqPos ifrom = lit.GetRange().GetFrom();
  1120.             TSeqPos ito   = lit.GetRange().GetTo();
  1121.             
  1122.             char bases[2];
  1123.             bases[1] = '';
  1124.             bool neg = lit.GetStrand () == eNa_strand_minus;
  1125.             for (TSeqPos pos = neg ? ito : ifrom;
  1126.                  (neg ? (pos - offset >= ifrom) : (pos + offset <= ito))  && 
  1127.                  idx != prot_seq.length();
  1128.                  (neg ? pos -= 3 : pos += 3), ++idx) 
  1129.             {
  1130.                 seq_start = neg ? pos - offset : pos + offset;
  1131.                 x_Color( CSeqGraphicColorConfig::eSeq_ProtTranslated );
  1132.                 if (type == eTranslatedSeq) {  // drawing translated sequence
  1133.                     bases[0] = trans_seq[idx];
  1134.                     if (prot_seq[idx] != trans_seq[idx]) {
  1135.                         x_Color(CSeqGraphicColorConfig::eSeq_ProtMismatch); // Mismatch
  1136.                     }
  1137.                 } else { // drawing actual sequence
  1138.                     bases[0] = prot_seq[idx];
  1139.                 }
  1140.                 m_Font_Helv10.TextOut(seq_start - offsetX, bases_y - off - offsetY, bases);
  1141.                 
  1142.                 
  1143.                 // for selected feature show original sequence below
  1144.                 if (selected) {
  1145.                     x_Color( CSeqGraphicColorConfig::eSeq_ProtOriginal );
  1146.                     
  1147.                     string main_seq, tmp_seq;
  1148.                     vec.GetSeqData(seq_start - 1, seq_start + 2, tmp_seq);
  1149.                     
  1150.                     if (neg) {  // reverse sequence on negative strand
  1151.                         CSeqManip::Complement(tmp_seq, CSeqUtil::e_Iupacna,
  1152.                                    0, tmp_seq.length(), main_seq);
  1153.                     } else {
  1154.                         main_seq = tmp_seq;
  1155.                     }
  1156.                     
  1157.                     GLfloat s_start = seq_start - offsetX - 0.8f;
  1158.                     
  1159.                     for (TSeqPos bp = 0;  bp != main_seq.length();  bp++) {
  1160.                         bases[0] = main_seq[bp];
  1161.                         m_Font_Helv8.TextOut(s_start, bases_y + 9 - offsetY, bases);
  1162.                         s_start += 0.8f;
  1163.                     }
  1164.                 }
  1165.             }
  1166.             // Use correct offset for the next interval
  1167.             int diff = neg ? seq_start - ifrom : ito - seq_start;
  1168.             if (diff == 2) {
  1169.                 offset = 0;
  1170.             } else if (diff == 1) {
  1171.                 offset = 1;
  1172.             } else if (diff == 0) {
  1173.                 offset = 2;
  1174.             }
  1175.         } // for
  1176.     }  // done with protein sequence
  1177. }
  1178. GLfloat 
  1179. CDefaultPolicy::x_CenterText(CGlPane& pane, TModelRect rc, GLfloat width) const
  1180. {
  1181.     return rc.Left() + rc.Width() / 2.0f - 
  1182.         pane.UnProjectWidth(TVPUnit(width)) / 2.0f;
  1183. }
  1184. size_t CDefaultPolicy::x_GetSeqAnnotIndex(const CSeq_annot_Handle& annot) const
  1185. {
  1186.     TNamedAnnots::const_iterator iter = m_Annots.find(annot.GetName());
  1187.     if (iter == m_Annots.end()) {
  1188.         m_Annots[annot.GetName()] = m_Annots.size();
  1189.         iter = m_Annots.find(annot.GetName());
  1190.     }
  1191.     return iter->second;
  1192. }
  1193. void CDefaultPolicy::x_DrawQuad(CGlPane& pane,
  1194.     TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2) const
  1195. {
  1196.     TModelUnit offsetX = pane.GetOffsetX();
  1197.     TModelUnit offsetY = pane.GetOffsetY();
  1198.     glVertex2f(x1 - offsetX,     y1 - offsetY);
  1199.     glVertex2f(x2 - offsetX + 1, y1 - offsetY);
  1200.     glVertex2f(x2 - offsetX + 1, y2 - offsetY);
  1201.     glVertex2f(x1 - offsetX,     y2 - offsetY);
  1202. }
  1203. void CDefaultPolicy::x_DrawSelection(CGlPane& pane,
  1204.     TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2) const
  1205. {
  1206.     TModelUnit offsetX = pane.GetOffsetX();
  1207.     TModelUnit offsetY = pane.GetOffsetY();
  1208.     glVertex2f(x1 - offsetX, y1 - offsetY);
  1209.     glVertex2f(x1 - offsetX, y2 - offsetY);
  1210.     glVertex2f(x1 - offsetX, y2 - offsetY);
  1211.     glVertex2f(x2 - offsetX+1, y2 - offsetY);
  1212.     glVertex2f(x2 - offsetX+1, y2 - offsetY);
  1213.     glVertex2f(x2 - offsetX+1, y1 - offsetY);
  1214.     glVertex2f(x1 - offsetX, y1 - offsetY);
  1215.     glVertex2f(x2 - offsetX+1, y1 - offsetY);
  1216. }
  1217. // Is LayoutObject clicked? Uses model coordinates
  1218. bool CDefaultPolicy::x_IsObjectClicked(CGlPane& pane, const CLayoutObject* obj, 
  1219.         GLfloat row_y, bool selected) const
  1220. {
  1221.     TModelUnit height = GetRowHeight(pane, obj, selected);
  1222.     if (m_LastClick.Y() >=row_y &&  m_LastClick.Y() <= row_y + height) {
  1223.         return obj->GetObject( TSeqPos(m_LastClick.X()) ) != NULL;
  1224.     }
  1225.     return false;
  1226. }
  1227. // Is feature label clicked? Uses pixels. 
  1228. // Only in overview mode.
  1229. bool CDefaultPolicy::x_IsFeatLabelClicked(CGlPane& pane, 
  1230.                     const CLayoutFeatLabel* lbl, GLfloat row_y) const
  1231. {
  1232.     const TModelRect& rc = pane.GetVisibleRect();
  1233.     int label_width = kLabelsColWidth;
  1234.     TModelUnit width = pane.UnProjectWidth(label_width);
  1235.     TModelUnit offset = width * lbl->GetColumn();
  1236.     TModelRect rcM(rc.Left() + offset, row_y);
  1237.     rcM.SetSize(width, x_GetRowHeight(pane, lbl, false) );
  1238.     return rcM.PtInRect(m_LastClick.X(), m_LastClick.Y());
  1239. }
  1240. TModelUnit CDefaultPolicy::x_CalcAlignHeight(const CLayoutAlign* align) const
  1241. {
  1242.     const CAlnVec& aln_mgr = align->GetAlignMgr();
  1243.     TModelUnit height = m_Font_Helv10.TextHeight() + 4 +
  1244.                 (kAlnElementHeight + 1) * (aln_mgr.GetNumRows() - 1);
  1245.     return height;
  1246. }
  1247. void CDefaultPolicy::x_Color(CSeqGraphicColorConfig::EDisplayElement e) const
  1248. {
  1249.     CGlColor color = m_ConfigSettings->GetElementColor(e);
  1250.     glColor3f(color.GetRed(), color.GetGreen(), color.GetBlue());
  1251. }
  1252. bool CDefaultPolicy::ProcessObject(CGlPane& pane, const CLayoutObject* obj,
  1253.                     TModelUnit row, EObj_IterMode mode, bool selected) const
  1254. {
  1255.     GLfloat row_y = row;
  1256.     
  1257.     const CLayoutFeat*      feat   = dynamic_cast<const CLayoutFeat*>      (obj);
  1258.     const CLayoutAlign*     align  = dynamic_cast<const CLayoutAlign*>     (obj);
  1259.     const CLayoutAlignSmear* smear = dynamic_cast<const CLayoutAlignSmear*>(obj);
  1260.     const CLayoutProtProd*  prot   = dynamic_cast<const CLayoutProtProd*>  (obj);
  1261.     const CLayoutGraph*     graph  = dynamic_cast<const CLayoutGraph*>     (obj);
  1262.     const CLayoutFeatLabel* label  = dynamic_cast<const CLayoutFeatLabel*> (obj);
  1263.     const CLayoutComment*   comm   = dynamic_cast<const CLayoutComment*>   (obj);
  1264.     const CLayoutFeatPack*  pack   = dynamic_cast<const CLayoutFeatPack*>  (obj);
  1265.     const CLayoutHistogram* hist   = dynamic_cast<const CLayoutHistogram*> (obj);
  1266.     const CLayoutSeqMap*    seg    = dynamic_cast<const CLayoutSeqMap*>    (obj);
  1267.     const CLayoutSequence*  seqs   = dynamic_cast<const CLayoutSequence*>  (obj);
  1268.     const CLayoutMatePair*  pair   = dynamic_cast<const CLayoutMatePair*>  (obj); 
  1269.     const CLayoutPWAlign* pw_align = dynamic_cast<const CLayoutPWAlign*>   (obj); 
  1270.     switch (mode) {
  1271.     case eDrawObjectGrid:
  1272.         x_DrawGridLine(pane, obj, row_y);
  1273.         break;
  1274.     case eDrawObjectLines:
  1275.     case eDrawObjectQuads:
  1276.     case eDrawObjectLabel:
  1277.         if (comm) {
  1278.             x_DrawComments(pane, comm, row_y, mode, selected);
  1279.         } else if (seg) {
  1280.             x_DrawSeqSegment(pane, seg, row_y, mode, selected);
  1281.         } else if (pw_align) {
  1282.             x_DrawPWAlign(pane, pw_align, row_y, mode, selected);
  1283.         } else if (seqs) {
  1284.             x_DrawSequence(pane, seqs, row_y, mode, selected);
  1285.         } else if (hist) {
  1286.             x_DrawHistogram(pane, hist, row_y, mode, selected);
  1287.         } else if (label != NULL) {
  1288.             x_DrawFeatLabel(pane, label, row_y, mode, selected);
  1289.         } else if (prot != NULL) {
  1290.             if (mode == eDrawObjectLabel) {
  1291.                 x_DrawProteinProduct(pane, prot, row_y, eProteinSeq, selected);
  1292.             } else {
  1293.                 x_DrawFeature(pane, prot, row_y, mode, selected);
  1294.             }
  1295.         } else if (feat != NULL) {
  1296.             x_DrawFeature(pane, feat, row_y, mode, selected);
  1297.             const CSeqFeatData& data = feat->GetFeature().GetData();
  1298.             if (mode == eDrawObjectLabel  &&
  1299.                 data.Which() == CSeqFeatData::e_Cdregion) {
  1300.                 x_DrawProteinProduct(pane, feat, row_y,
  1301.                                      eTranslatedSeq, selected);
  1302.             }
  1303.         } else if (align != NULL) {
  1304.             x_DrawAlignment(pane, align, row_y, mode, selected);
  1305.         } else if (smear != NULL) {
  1306.             x_DrawAlignmentSmear(pane, smear, row_y, mode, selected);
  1307.         } else if (graph != NULL) {
  1308.             x_DrawSeqGraph(pane, graph, row_y, mode, selected);
  1309.         } else if (pack != NULL) {
  1310.             x_DrawFeatPack(pane, pack, row_y, mode, selected);
  1311.         } else if (pair != NULL) {
  1312.             x_DrawMatePair(pane, pair, row_y, mode, selected);
  1313.         }
  1314.         break;
  1315.     case eCalcObjectRows:
  1316.         break;
  1317.     case eGetHTMLAreas:
  1318.         x_GetHTMLActiveAreas(pane, obj, row_y, selected);
  1319.         break;
  1320.     case eObjectHitTest:
  1321.         if (label) {
  1322.             return x_IsFeatLabelClicked(pane, label, row_y);
  1323.         } else {
  1324.             return x_IsObjectClicked(pane, obj, row_y, selected);
  1325.         }
  1326.         break;
  1327.     default:
  1328.         break;
  1329.     }
  1330.     return false;
  1331. }
  1332. void CDefaultPolicy::x_GetHTMLActiveAreas(CGlPane& pane,
  1333.                                           const CLayoutObject* obj, 
  1334.                                           GLfloat row_y, bool selected) const
  1335. {
  1336.     string title, tooltip;
  1337.     const CLayoutFeatLabel* label = dynamic_cast<const CLayoutFeatLabel*> (obj);
  1338.     const CLayoutMatePair*  mpair = dynamic_cast<const CLayoutMatePair*> (obj);
  1339.     if (!m_ActiveAreas  ||  label) {
  1340.         return;
  1341.     }
  1342.     
  1343.     if (mpair) {
  1344.         const CLayoutMatePair::TAlignList& pw_aligns = mpair->GetSeqAligns();
  1345.         ITERATE(CLayoutMatePair::TAlignList, iter, pw_aligns) {
  1346.             GetTitle(iter->GetPointer(), &title, CLabel::eDefault);
  1347.             GetTitle(iter->GetPointer(), &tooltip, CLabel::eTooltipDetailed);
  1348.             x_AddGetHTMLActiveElement(title, tooltip, pane,  
  1349.                 iter->GetPointer(), row_y, selected);
  1350.         }
  1351.     } else {
  1352.         GetTitle(obj, &title, CLabel::eDefault);
  1353.         GetTitle(obj, &tooltip, CLabel::eTooltipDetailed);
  1354.         x_AddGetHTMLActiveElement(title, tooltip, pane, obj, row_y, selected);
  1355.     }
  1356. }
  1357. void CDefaultPolicy::x_AddGetHTMLActiveElement(string title, string tooltip,
  1358.         CGlPane& pane, const CLayoutObject* obj,  
  1359.         GLfloat row_y, bool selected) const
  1360. {
  1361.     TSeqRange r = obj->GetLocation().GetTotalRange();    
  1362.     TVPUnit x1  = pane.ProjectX (r.GetFrom());
  1363.     TVPUnit x2  = pane.ProjectX (r.GetTo()  );
  1364.     TVPUnit y1  = TVPUnit(row_y);
  1365.     TVPUnit y2  = TVPUnit(row_y + GetRowHeight(pane, obj, selected));
  1366.     
  1367.     x1 = max(0, x1);
  1368.     x2 = min(pane.GetViewport().Right(), x2);
  1369.     
  1370.     //cout << x1 << "t" << x2 << "t" << y1 << "t" << y2 << endl;
  1371.     CHTMLActiveArea area(CHTMLActiveArea::eCheckBox,
  1372.                          TVPRect(x1, y2, x2, y1),
  1373.                          title, tooltip, "toggle_select");
  1374.     /*pane.OpenPixels();
  1375.     glColor3f(0.0f, 0.0f, 0.0f);  // Black
  1376.     glBegin(GL_LINE_LOOP);
  1377.     glVertex2f(rc_bounds.Left(),   pane.GetViewport().Height()-rc_bounds.Top()+5);
  1378.     glVertex2f(rc_bounds.Right(),  pane.GetViewport().Height()-rc_bounds.Top()+5);
  1379.     glVertex2f(rc_bounds.Right(),  pane.GetViewport().Height()-rc_bounds.Bottom()+5);
  1380.     glVertex2f(rc_bounds.Left(),   pane.GetViewport().Height()-rc_bounds.Bottom()+5);
  1381.     glEnd();
  1382.     pane.Close();*/
  1383.     
  1384.     m_ActiveAreas->push_back(area);
  1385. }
  1386. bool CDefaultPolicy::x_IsSeqLettersFit(CGlPane& pane) const
  1387. {
  1388.     return pane.GetScaleX() <= 1.0f / kPixPerBase4Sequence;
  1389. }
  1390. void CDefaultPolicy::x_DrawGridLine(CGlPane& pane, 
  1391.         const CLayoutObject* obj, GLfloat row_y) const
  1392. {
  1393.     const TModelRect& rc = pane.GetModelLimitsRect();
  1394.     glVertex2f(rc.Left()  - pane.GetOffsetX(), row_y - pane.GetOffsetY() );
  1395.     glVertex2f(rc.Right() - pane.GetOffsetX(), row_y - pane.GetOffsetY() );
  1396. }
  1397. TModelUnit CDefaultPolicy::GetRowHeight(CGlPane& pane, const CLayoutObject* obj, bool selected) const
  1398. {
  1399.     const CLayoutComment*   comm   = dynamic_cast<const CLayoutComment*>   (obj);
  1400.     const CLayoutFeat*      feat   = dynamic_cast<const CLayoutFeat*>      (obj);
  1401.     const CLayoutAlign*     align  = dynamic_cast<const CLayoutAlign*>     (obj);
  1402.     const CLayoutAlignSmear* smear = dynamic_cast<const CLayoutAlignSmear*> (obj);
  1403.     const CLayoutProtProd*  prot   = dynamic_cast<const CLayoutProtProd*>  (obj);
  1404.     const CLayoutGraph*     graph  = dynamic_cast<const CLayoutGraph*>     (obj);
  1405.     const CLayoutFeatLabel* label  = dynamic_cast<const CLayoutFeatLabel*> (obj);
  1406.     const CLayoutFeatPack*  pack   = dynamic_cast<const CLayoutFeatPack*>  (obj);
  1407.     const CLayoutHistogram* hist   = dynamic_cast<const CLayoutHistogram*> (obj);
  1408.     const CLayoutSeqMap*    seg    = dynamic_cast<const CLayoutSeqMap*>    (obj);
  1409.     const CLayoutSequence*  seqs   = dynamic_cast<const CLayoutSequence*>  (obj);
  1410.     const CLayoutMatePair*  pair   = dynamic_cast<const CLayoutMatePair*>  (obj); 
  1411.     const CLayoutPWAlign*   pw_aln = dynamic_cast<const CLayoutPWAlign*>   (obj); 
  1412.                         
  1413.     if (pw_aln) return x_GetRowHeight(pane, pw_aln,selected);
  1414.     if (seqs)   return x_GetRowHeight(pane, seqs,  selected);
  1415.     if (comm)   return x_GetRowHeight(pane, comm,  selected);
  1416.     if (label)  return x_GetRowHeight(pane, label, selected);
  1417.     if (align)  return x_GetRowHeight(pane, align, selected);
  1418.     if (smear)  return x_GetRowHeight(pane, smear, selected);
  1419.     if (prot)   return x_GetRowHeight(pane, prot,  selected);
  1420.     if (graph)  return x_GetRowHeight(pane, graph, selected);
  1421.     if (feat)   return x_GetRowHeight(pane, feat,  selected);
  1422.     if (pack)   return x_GetRowHeight(pane, pack,  selected);
  1423.     if (hist)   return x_GetRowHeight(pane, hist,  selected);
  1424.     if (seg)    return x_GetRowHeight(pane, seg,   selected);
  1425.     if (pair)   return x_GetRowHeight(pane, pair,  selected);
  1426.     
  1427.     return 0;
  1428. }
  1429. void CDefaultPolicy::GetTitle(const CLayoutObject* obj, string* title,
  1430.         CLabel::ELabelType type) const 
  1431. {
  1432.     const CLayoutFeat*      feat  = dynamic_cast<const CLayoutFeat*>      (obj);
  1433.     const CLayoutAlign*     align = dynamic_cast<const CLayoutAlign*>     (obj);
  1434.   //const CLayoutProtProd*  prot  = dynamic_cast<const CLayoutProtProd*>  (obj);
  1435.     const CLayoutGraph*     graph = dynamic_cast<const CLayoutGraph*>     (obj);
  1436.   //const CLayoutFeatLabel* label = dynamic_cast<const CLayoutFeatLabel*> (obj);
  1437.     const CLayoutFeatPack*   pack = dynamic_cast<const CLayoutFeatPack*>  (obj);
  1438.     const CLayoutHistogram* hist  = dynamic_cast<const CLayoutHistogram*> (obj);
  1439.     const CLayoutSeqMap*    seg   = dynamic_cast<const CLayoutSeqMap*>    (obj);
  1440.     const CLayoutSequence*  seqs  = dynamic_cast<const CLayoutSequence*>  (obj);
  1441.     const CLayoutMatePair*  pair  = dynamic_cast<const CLayoutMatePair*>  (obj); 
  1442.     const CLayoutPWAlign*  pw_aln = dynamic_cast<const CLayoutPWAlign*>   (obj); 
  1443.             
  1444.     if (pw_aln) {
  1445.         x_GetTitle(pw_aln, title, type);
  1446.     } else if (align) {
  1447.         x_GetTitle(align, title, type);
  1448.     } else if (graph) {
  1449.         x_GetTitle(graph, title, type);
  1450.     } else if (feat) {
  1451.         x_GetTitle(feat, title, type);
  1452.     } else if (pack) {
  1453.         x_GetTitle(pack, title, type);
  1454.     } else if (hist) {
  1455.         x_GetTitle(hist, title, type);
  1456.     } else if (seg) {
  1457.         x_GetTitle(seg, title, type);
  1458.     } else if (seqs) {
  1459.         x_GetTitle(seqs, title, type);
  1460.     } else if (pair) {
  1461.         x_GetTitle(pair, title, type);
  1462.     }
  1463. }
  1464. void CDefaultPolicy::x_GetTitle(const CLayoutSeqMap* seg, string* title, 
  1465.         CLabel::ELabelType type) const
  1466. {
  1467.     if (title) {
  1468.         title->erase();
  1469.         CLabel::GetLabel(seg->GetSeqID(), title,
  1470.                         type, &m_Handle.GetScope());
  1471.     }
  1472. }
  1473. void CDefaultPolicy::x_GetTitle(const CLayoutSequence* seqs, string* title, 
  1474.         CLabel::ELabelType type) const
  1475. {
  1476.     *title = seqs->GetSequence(); //"Sequence Bar";
  1477. }
  1478. void CDefaultPolicy::x_GetTitle(const CLayoutHistogram* hist, string* title, 
  1479.         CLabel::ELabelType type) const
  1480. {
  1481.     *title = "Distribution Histogram for " + GetFeatConfigList()->
  1482.             GetDescription(hist->Which(), hist->Subtype()) + "(s)";
  1483. }
  1484. void CDefaultPolicy::x_GetTitle(const CLayoutFeatPack* pack, string* title, 
  1485.         CLabel::ELabelType type) const
  1486. {
  1487.     *title = "";
  1488. }
  1489. void CDefaultPolicy::x_GetTitle(const CLayoutFeat* feat, string* title, 
  1490.         CLabel::ELabelType type) const
  1491. {
  1492.     string tmp_type, tmp_content;
  1493.     x_GetLabels(feat->GetFeature(), m_Handle.GetScope(),
  1494.                 &tmp_type, &tmp_content, title);
  1495. }
  1496. void CDefaultPolicy::x_GetTitle(const CLayoutPWAlign* pw_aln, string* title, 
  1497.         CLabel::ELabelType type) const
  1498. {
  1499.     title->erase();
  1500.     const CAlnVec& aln_mgr = pw_aln->GetAlignMgr();
  1501.     
  1502.     // display the name of the seconds sequence (not the master seq.)
  1503.     CAlnMap::TNumrow row = m_Handle.IsSynonym(aln_mgr.GetSeqId(0)) ? 1 : 0;
  1504.     CLabel::GetLabel(aln_mgr.GetSeqId(row), title,
  1505.                      type, &m_Handle.GetScope());
  1506. }
  1507. void CDefaultPolicy::x_GetTitle(const CLayoutAlign* align, string* title, 
  1508.         CLabel::ELabelType type) const
  1509. {
  1510.     const CAlnVec& aln_mgr = align->GetAlignMgr();
  1511.     title->erase();
  1512.     
  1513.     // otherwise display the row count
  1514.     *title = "[Alignment] " +
  1515.         NStr::UIntToString(aln_mgr.GetNumRows()) + " sequences";
  1516. }
  1517. void CDefaultPolicy::x_GetTitle(const CLayoutGraph* graph, string* title, 
  1518.         CLabel::ELabelType type) const
  1519. {
  1520.     const CMappedGraph& gr = graph->GetGraph();
  1521.     *title = gr.IsSetTitle() ? gr.GetTitle() : "";    
  1522. }
  1523. void CDefaultPolicy::x_GetTitle(const CLayoutMatePair* pr, string* title, 
  1524.         CLabel::ELabelType type) const
  1525. {
  1526.     // It's a vector of CRefs
  1527.     const CLayoutMatePair::TAlignList& pw_aligns = pr->GetSeqAligns();
  1528.     
  1529.     *title = "Mate Pair: ";
  1530.     string tmp = "";
  1531.     ITERATE(CLayoutMatePair::TAlignList, iter, pw_aligns) {
  1532.         if (tmp.length() > 0) *title = *title + " / ";
  1533.         tmp.erase();
  1534.         x_GetTitle(iter->GetPointer(), &tmp, type);
  1535.         *title = *title + tmp;
  1536.     }
  1537. }
  1538. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1539.                                         const CLayoutMatePair* pr, 
  1540.                                         bool selected) const
  1541. {
  1542.     if (m_ConfigSettings->GetShowPWAlignLabels()) {
  1543.         return m_Font_Helv10.TextHeight() + 4 + 
  1544.             m_Font_Helv8.TextHeight() + kSpacerSize;
  1545.     } else {
  1546.         return m_Font_Helv8.TextHeight() + kSpacerSize;
  1547.     }
  1548. }
  1549. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1550.                                           const CLayoutSequence* seqs,
  1551.                                           bool selected) const
  1552. {
  1553.     return 20.0f + kSpacerSize;
  1554. }
  1555. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1556.                                           const CLayoutHistogram* hist,
  1557.                                           bool selected) const
  1558. {
  1559.     return 20.0f + kSpacerSize;
  1560. }
  1561. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1562.                                           const CLayoutSeqMap* seg,
  1563.                                           bool selected) const
  1564. {
  1565.     return 3.0f + kSpacerSize;
  1566. }
  1567. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1568.                                           const CLayoutComment* comm,
  1569.                                           bool selected) const
  1570. {
  1571.     return kCommentFontSize + kSpacerSize;
  1572. }
  1573. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1574.                                           const CLayoutFeatPack* pack,
  1575.                                           bool selected) const
  1576. {
  1577.     return 20.0f + kSpacerSize;
  1578. }
  1579. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1580.                                           const CLayoutFeat* feat,
  1581.                                           bool selected) const
  1582. {
  1583.     const CSeqFeatData& data = feat->GetFeature().GetData();
  1584.     if (selected  &&  data.Which() == CSeqFeatData::e_Cdregion 
  1585.                   &&  x_IsSeqLettersFit(pane) ) {
  1586.         // one and a half row for selected feature
  1587.         return 30.0f + kSpacerSize;
  1588.     } else {
  1589.         return 20.0f + kSpacerSize;
  1590.     }
  1591. }
  1592. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1593.                                           const CLayoutAlign* align,
  1594.                                           bool selected) const
  1595. {
  1596.     TModelUnit height = x_CalcAlignHeight(align);
  1597.     return height;
  1598. }
  1599. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1600.                                           const CLayoutPWAlign* pw_aln,
  1601.                                           bool selected) const
  1602. {
  1603.     if (m_ConfigSettings->GetShowPWAlignLabels()) {
  1604.         return m_Font_Helv10.TextHeight() + 4 + 
  1605.             m_Font_Helv8.TextHeight() + kSpacerSize;
  1606.     } else {
  1607.         return m_Font_Helv8.TextHeight() + kSpacerSize;
  1608.     }
  1609. }
  1610. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1611.                                           const CLayoutAlignSmear* align,
  1612.                                           bool selected) const
  1613. {
  1614.     return 20.f + kSpacerSize;
  1615. }
  1616. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1617.                                           const CLayoutFeatLabel* label,
  1618.                                           bool selected) const
  1619. {
  1620.     return kCommentFontSize + kSpacerSize;
  1621. }
  1622. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1623.                                           const CLayoutGraph* graph,
  1624.                                           bool selected) const
  1625. {
  1626.     return 20.f + kSpacerSize;
  1627. }
  1628. TModelUnit CDefaultPolicy::x_GetRowHeight(CGlPane& pane, 
  1629.                                           const CLayoutProtProd* prot,
  1630.                                           bool selected) const
  1631. {
  1632.     if (selected  &&  x_IsSeqLettersFit(pane) ) {
  1633.         return 30.0f + kSpacerSize;
  1634.     } else {
  1635.         return 20.0f + kSpacerSize;
  1636.     }
  1637. }
  1638. END_NCBI_SCOPE
  1639. /*
  1640.  * ===========================================================================
  1641.  * $Log: default_policy.cpp,v $
  1642.  * Revision 1000.3  2004/06/01 21:12:33  gouriano
  1643.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.41
  1644.  *
  1645.  * Revision 1.41  2004/05/21 22:27:55  gorelenk
  1646.  * Added PCH ncbi_pch.hpp
  1647.  *
  1648.  * Revision 1.40  2004/05/21 13:51:27  lebedev
  1649.  * 2 pixels space between sequence graphs added. Display of min and max values in the graph title.
  1650.  *
  1651.  * Revision 1.39  2004/05/14 16:00:27  lebedev
  1652.  * Respect color defines for Mate Pairs error codes. Draw pair wise alignment strand
  1653.  * indicators as arrows. Use CLabel::eTooltipDetailed mode for tooltips.
  1654.  *
  1655.  * Revision 1.38  2004/05/14 14:13:16  dicuccio
  1656.  * Use CLabel instead of manually picking a label
  1657.  *
  1658.  * Revision 1.37  2004/05/13 18:42:20  lebedev
  1659.  * Properly handle sequence for negative strand alignments
  1660.  *
  1661.  * Revision 1.36  2004/05/11 17:58:54  lebedev
  1662.  * Highlight Mate Pairs background based on library ID. Highlight mate pair with errors with shades of red.
  1663.  *
  1664.  * Revision 1.35  2004/05/07 15:37:13  dicuccio
  1665.  * Use CLabel instead of CSeqUtils::GetLabel()
  1666.  *
  1667.  * Revision 1.34  2004/05/07 11:12:52  lebedev
  1668.  * Option to show/hide labels for pairwise alignments and mate pairs added.
  1669.  *
  1670.  * Revision 1.33  2004/04/22 18:15:04  lebedev
  1671.  * Allow Mate Pairs to have separate selection for each alignment inside.
  1672.  *
  1673.  * Revision 1.32  2004/04/21 16:35:38  lebedev
  1674.  * Support for pair-wise alignments added. Rendering of Mate Pairs changed.
  1675.  * Return multiple HTML Active areas for Mate Pair objects.
  1676.  *
  1677.  * Revision 1.31  2004/04/20 19:20:18  dicuccio
  1678.  * #ifdef'd mate pair rendering code pending rewrite
  1679.  *
  1680.  * Revision 1.30  2004/04/19 15:44:23  lebedev
  1681.  * Use color form configuration engine for Mate-Pairs. Highlight link between pairs.
  1682.  *
  1683.  * Revision 1.29  2004/04/16 14:52:01  dicuccio
  1684.  * SetConfig() takes pointer, not CRef<>.  Formatting changes
  1685.  *
  1686.  * Revision 1.28  2004/04/15 13:04:51  lebedev
  1687.  * Selection for MatePairs added.
  1688.  *
  1689.  * Revision 1.27  2004/04/14 14:00:41  vasilche
  1690.  * MSVC doesn't like templates' names as function arguments' names.
  1691.  *
  1692.  * Revision 1.26  2004/04/14 11:25:48  lebedev
  1693.  * Added rendering of Mate Pairs.
  1694.  *
  1695.  * Revision 1.25  2004/04/12 18:47:57  dicuccio
  1696.  * Adjusted rendering of alignments - fixed rendering of gaps.  Formatting changes
  1697.  *
  1698.  * Revision 1.24  2004/04/07 13:10:56  dicuccio
  1699.  * Use CSeq_annot_Handle for proper annotation name handling
  1700.  *
  1701.  * Revision 1.23  2004/04/06 13:41:32  dicuccio
  1702.  * Formatting changes.  Replaced if block with switch statement.  Changed rendering of HTML active areas to upse CHTMLActiveArea directly
  1703.  *
  1704.  * Revision 1.22  2004/04/06 11:58:18  lebedev
  1705.  * Do not project y coordinate in the x_GetHTMLActiveAreas method.
  1706.  *
  1707.  * Revision 1.21  2004/03/31 16:08:58  lebedev
  1708.  * Methods to get HTML active areas added.
  1709.  *
  1710.  * Revision 1.20  2004/03/30 13:58:37  lebedev
  1711.  * Use elements colors from configuration instead of setting colors directly.
  1712.  *
  1713.  * Revision 1.19  2004/03/29 15:12:20  dicuccio
  1714.  * Changed default height of alignment bars to 5 pixels (was 2).  Fixed rendering
  1715.  * of - strand alignments (swap start/stop).  Fixed rendering of sequence letters
  1716.  * - use ArrayTextOut() instead of TextOut
  1717.  *
  1718.  * Revision 1.18  2004/03/26 15:46:00  lebedev
  1719.  * Rendering of SeqGraphs fixed
  1720.  *
  1721.  * Revision 1.17  2004/03/23 12:33:55  lebedev
  1722.  * Made sequence and histograms bars a layout objects in the object panel.
  1723.  * Made segment map a number of layout objects. Get rid of fixed size rows in the object panel.
  1724.  *
  1725.  * Revision 1.16  2004/03/22 16:54:15  rsmith
  1726.  * draw alignment smears.
  1727.  *
  1728.  * Revision 1.15  2004/03/11 17:53:06  dicuccio
  1729.  * Deprecated typedefs TPosition, TDimension, TIndex, TColor.  Use TSeqRange instead of TRange
  1730.  *
  1731.  * Revision 1.14  2004/03/05 17:40:57  dicuccio
  1732.  * Use CSeqUtil::GetLabel() instead of home-grown solution
  1733.  *
  1734.  * Revision 1.13  2004/02/24 14:47:31  lebedev
  1735.  * Support for new types of layout objects added
  1736.  *
  1737.  * Revision 1.12  2004/02/05 16:47:10  dicuccio
  1738.  * Fixed rendering of alignments: correctly hande discontinuous alignments
  1739.  *
  1740.  * Revision 1.11  2004/02/03 16:54:06  dicuccio
  1741.  * Fixed bug in rendering of alignments - was skipping alignment segments
  1742.  *
  1743.  * Revision 1.10  2004/02/02 16:35:10  dicuccio
  1744.  * Fixed rendering issues in alignments - use proper starting coordinate
  1745.  *
  1746.  * Revision 1.9  2004/01/30 16:54:39  dicuccio
  1747.  * Fixed bugs in rendering of alignments - use correct calculation for start/stop
  1748.  * position of aligned segments
  1749.  *
  1750.  * Revision 1.8  2004/01/20 19:50:58  dicuccio
  1751.  * FIxed rendering of alignments - trap case in which trailing segments are gaps
  1752.  *
  1753.  * Revision 1.7  2004/01/16 18:43:15  dicuccio
  1754.  * Fixed issues in accessing invalid bioseq handles.  Reformatted some code.
  1755.  * Added scoping to catch variables declared inside of switch statements.
  1756.  *
  1757.  * Revision 1.6  2004/01/16 13:40:14  lebedev
  1758.  * Tooltips added
  1759.  *
  1760.  * Revision 1.5  2004/01/13 20:39:33  dicuccio
  1761.  * Minor change to labels: don't include type if product location is shown
  1762.  *
  1763.  * Revision 1.4  2004/01/05 21:25:05  dicuccio
  1764.  * Code clean-up.  Corrected issue with protein product features not appearing in
  1765.  * the correct color; standardized use of x_SetFeatureColor()
  1766.  *
  1767.  * Revision 1.3  2004/01/05 19:13:26  dicuccio
  1768.  * Code clean-up - fixed bracketing, indentation
  1769.  *
  1770.  * Revision 1.2  2004/01/05 17:50:19  dicuccio
  1771.  * Use x_GetLabels() to reduce code duplication.  Changed feature labels to
  1772.  * include product accessions where available.  Changed protein produc label to be
  1773.  * the accession.version
  1774.  *
  1775.  * Revision 1.1  2003/12/16 18:57:44  lebedev
  1776.  * Initial revision
  1777.  *
  1778.  * ===========================================================================
  1779.  */