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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: textaln_panel.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 21:08:00  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.12
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: textaln_panel.cpp,v 1000.2 2004/06/01 21:08:00 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.  */
  37. #include <ncbi_pch.hpp>
  38. #include "panel.hpp"
  39. #include <gui/widgets/aln_data/align_ds.hpp>
  40. #include <gui/opengl/glcolortable.hpp>
  41. #include <gui/opengl/glbitmapfont.hpp>
  42. #include <objects/seqloc/Seq_id.hpp>
  43. #include <objmgr/util/feature.hpp>
  44. #include <objmgr/util/sequence.hpp>
  45. #include <FL/fl_draw.H>
  46. #include <FL/Fl_Tooltip.H>
  47. BEGIN_NCBI_SCOPE
  48. USING_SCOPE(ncbi::objects);
  49. const int  kFontSize      = 10;  // font size for labels and sequence
  50. const int  kFontWidth     =  9;  // font width
  51. const int  kCellWidth     = 10;  // size of one element in the grid
  52. const int  kCellHeight    = 13;  // do not set less than that
  53. // or features may not fit
  54. const size_t      kUnknowIdx    = ((size_t) (-1));
  55. const string      kLabels       = "Labels";
  56. const string      kPosition     = "Position";
  57. CTextAlnPanel::CTextAlnPanel(int x, int y, int w, int h, const char* label)
  58.     : Fl_Gl_Window(x, y, w, h, label)
  59.     , m_Font_8x13(CGlBitmapFont::eBitmap8x13)
  60. {
  61.     m_DS              = NULL;
  62.     m_BackgroundColor = FL_WHITE;
  63.     m_SelectionColor  = FL_BLUE;
  64.     m_NumbersColor    = FL_BLUE;
  65.     m_GridColor       = FL_GRAY;
  66.     m_SequenceColor   = FL_BLACK;
  67.     m_MismatchColor   = FL_RED;
  68.     m_AlnWidth        = 0;
  69.     m_AlnHeight       = 0;
  70.     m_Anchor          = kUnknowIdx;
  71.     m_ShowSeqAsDots   = false;
  72.     m_featDisp        = CTextAlnView::eOff;
  73. }
  74. CTextAlnPanel::~CTextAlnPanel()
  75. {
  76.     // delete m_DS;
  77. }
  78. TSignedSeqPos CTextAlnPanel::x_GetStartAt(size_t idx, TNumseg seg) const
  79. {
  80.     return m_DS->GetAlnMgr().GetStart(idx, seg);
  81. }
  82. TSeqPos CTextAlnPanel::x_GetAlnWidth(void) const
  83. {
  84.     return m_DS->GetAlnMgr().GetAlnStop();
  85. }
  86. CTextAlnPanel::TDim CTextAlnPanel::x_GetAlnHeigth(void) const
  87. {
  88.     return m_DS->GetAlnMgr().GetNumRows();
  89. }
  90. void CTextAlnPanel::x_PrepareData(void)
  91. {
  92.     m_ScrX = 0;
  93.     m_ScrY = 0;
  94.     m_AlnWidth  = x_GetAlnWidth();
  95.     m_AlnHeight = x_GetAlnHeigth();
  96.     m_ParaG.clear();
  97.     for (TNumrow idx = 0; idx != m_AlnHeight; idx++) {
  98.         if (m_featDisp == CTextAlnView::eAll  ||  
  99.             (m_featDisp == CTextAlnView::eBase && idx == 0)) {
  100.             x_AddFeaturesAtIndex(idx);
  101.         }
  102.         CParaG para(CParaG::eSequence, idx);
  103.         m_ParaG.push_back(para);
  104.         x_AddInsertsAtIndex(idx);
  105.     }
  106. }
  107. void CTextAlnPanel::x_AddInsertsAtIndex(size_t idx)
  108. {
  109.     CRef<CAlnMap::CAlnChunkVec> chunk_vec = m_DS->GetAlnMgr().GetAlnChunks
  110.         (idx, CAlnMap::TSignedRange(0, m_AlnWidth), CAlnVec::fInsertsOnly);
  111.     if (chunk_vec->size() > 0) {
  112.         CParaG para(CParaG::eInsertion, idx);
  113.         m_ParaG.push_back(para);
  114.     }
  115. }
  116. void CTextAlnPanel::x_AddFeaturesAtIndex(size_t idx)
  117. {
  118.     const CBioseq_Handle& handle = m_DS->GetAlnMgr().GetBioseqHandle(idx);
  119.     for (CFeat_CI feat_it(handle, 0, 0, CSeqFeatData::e_not_set);
  120.          feat_it;  ++feat_it) {
  121.         CSeqFeatData::E_Choice type = (*feat_it).GetData().Which();
  122.         if (type == CSeqFeatData::e_Gene || type == CSeqFeatData::e_Rna ||
  123.             type == CSeqFeatData::e_Cdregion || type == CSeqFeatData::e_Prot) {
  124.             const CMappedFeat& feat = *feat_it;
  125.             CParaG para(CParaG::eFeature, idx,
  126.                         new CLayoutFeat(*new CMappedFeat(feat)));
  127.             m_ParaG.push_back(para);
  128.         }
  129.     }
  130. }
  131. void CTextAlnPanel::ShowSequenceAsDots(bool show_dots)
  132. {
  133.     m_ShowSeqAsDots = show_dots;
  134.     redraw();
  135. }
  136. void CTextAlnPanel::SetAnchor(size_t idx)
  137. {
  138.     m_Anchor = idx;
  139.     m_DS->SetAlnMgr().SetAnchor(idx);
  140.     x_PrepareData();
  141.     invalidate();
  142.     redraw();
  143. }
  144. void CTextAlnPanel::UnsetAnchor(void)
  145. {
  146.     m_Anchor = kUnknowIdx;
  147.     m_DS->SetAlnMgr().UnsetAnchor();
  148.     x_PrepareData();
  149.     invalidate();
  150.     redraw();
  151. }
  152. void CTextAlnPanel::SetDataSource(CAlignDataSource* ds)
  153. {
  154.     m_DS = ds;
  155.     m_RowSelect.clear();  // reset selections
  156.     m_ColSelect.clear();
  157.     for (TNumrow idx = 0; idx != x_GetAlnHeigth(); idx++)
  158.         m_RowSelect.push_back(false);
  159.     for (size_t idx = 0; idx != x_GetAlnWidth(); idx++)
  160.         m_ColSelect.push_back(false);
  161.     x_PrepareData();
  162.     invalidate();
  163.     redraw();
  164. }
  165. void CTextAlnPanel::SelectAll(bool flag)
  166. {
  167.     if ( !m_DS ) return;
  168.     for (size_t idx = 0; idx != m_RowSelect.size(); idx++)
  169.         m_RowSelect[idx] = flag;
  170.     if (!flag) for (size_t idx = 0; idx != m_ColSelect.size(); idx++)
  171.         m_ColSelect[idx] = flag;
  172.     redraw();
  173. }
  174. void CTextAlnPanel::x_DrawSelection(int size, ESelectionType type) const
  175. {
  176.     glEnable(GL_BLEND);
  177.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  178.     glColor4f(0.1f, 0.1f, 0.1f, 0.1f);
  179.     glBegin(GL_QUADS);
  180.     if (type == eRow) {
  181.         for (TNumrow row = 0;  row != m_ParaG.size();  row++) {
  182.             if (m_RowSelect[m_ParaG[row].GetIndex()]) {
  183.                 GLfloat yy = GLfloat(row - m_ScrY) * kCellHeight;
  184.                 glVertex2f(0.0f, yy + kCellHeight);
  185.                 glVertex2f(size, yy + kCellHeight);
  186.                 glVertex2f(size, yy);
  187.                 glVertex2f(0.0f, yy);
  188.             }
  189.         }
  190.     } else {
  191.         for (TSeqPos col = 0;  col != m_AlnWidth;  col++) {
  192.             if (m_ColSelect[col]) {
  193.                 GLfloat xx = GLfloat(col - m_ScrX) * kCellWidth;
  194.                 glVertex2f(xx,              size);
  195.                 glVertex2f(xx + kCellWidth, size);
  196.                 glVertex2f(xx + kCellWidth, 0.0f);
  197.                 glVertex2f(xx,              0.0f);
  198.             }
  199.         }    
  200.     }
  201.     glEnd();
  202.     glDisable(GL_BLEND);
  203. }
  204. void CTextAlnPanel::x_DrawGrid()
  205. {
  206.     gl_color(m_GridColor);
  207.     glBegin(GL_LINES);
  208.     for (TSeqPos col = 0;  col != m_AlnWidth + 1;  col++) {
  209.         GLfloat xx = GLfloat(col - m_ScrX) * kCellWidth;
  210.         glVertex2f(xx, 0.0f);
  211.         glVertex2f(xx, m_Height);
  212.     }
  213.     for (TNumrow row = 0;  row != m_ParaG.size();  row++) {
  214.         GLfloat yy = GLfloat(row - m_ScrY) * kCellHeight;
  215.         glVertex2f(0.0f, yy);
  216.         glVertex2f(m_BP[2], yy);
  217.     }
  218.     glEnd();
  219.     x_DrawSelection(m_BP[2], eRow);
  220.     x_DrawSelection(m_BP[3], eCol);
  221. }
  222. void CTextAlnPanel::x_DrawSequence(TNumrow row, size_t idx) const
  223. {
  224.     string seq_draw, seq_base;
  225.     TSeqPos start  = m_ScrX;
  226.     TSeqPos finish = m_ScrX + m_BP[2] / kCellWidth;
  227.     m_DS->GetAlnMgr().GetAlnSeqString(seq_draw, idx, 
  228.                                        CAlnMap::TSignedRange(start, finish));
  229.     m_DS->GetAlnMgr().GetAlnSeqString(seq_base,   0, 
  230.                                        CAlnMap::TSignedRange(start, finish));
  231.     GLfloat yy = GLfloat(row - m_ScrY + 1) * kCellHeight + 1;
  232.     for (TSeqPos x = 0;  x != seq_draw.length();  x++) {
  233.         GLfloat xx = GLfloat(x * kCellWidth);
  234.         string seq_this  = seq_draw.substr(x, 1);
  235.         string seq_other = seq_base.substr(x, 1);
  236.         if (seq_this == " ") seq_this = "-";  // AlnMgr problem fix
  237.         if (seq_this != seq_other) {
  238.             gl_color(m_MismatchColor);  // color mismatches
  239.         } else {
  240.             gl_color(m_SequenceColor);
  241.             if (m_ShowSeqAsDots  &&  idx != 0  &&  seq_this != "-") {
  242.                 // draw dots instead (but not on the base sequence)
  243.                 seq_this = ".";
  244.             }
  245.         }
  246.         m_Font_8x13.TextOut(xx, yy - 2, seq_this.c_str());
  247.     }
  248. }
  249. void CTextAlnPanel::x_DrawFeatures(TNumrow row, size_t idx) const
  250. {    
  251.     glEnable(GL_BLEND);
  252.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  253.     GLfloat width = 3;
  254.     const CSeq_loc& loc = m_ParaG[row].Feature()->GetLocation();
  255.     switch (m_ParaG[row].Feature()->GetFeature().GetData().Which()) {
  256.     case CSeqFeatData::e_Gene:
  257.         glColor4f(0.0f, 1.0f, 0.0f, 0.33f);
  258.         width = 3.0f;
  259.         break;
  260.     case CSeqFeatData::e_Rna:
  261.         glColor4f(0.0f, 0.0f, 1.0f, 0.5f);
  262.         width = 5.0f;
  263.         break;
  264.     case CSeqFeatData::e_Cdregion:
  265.         glColor4f(1.0f, 0.0f, 0.0f, 0.33f);
  266.         width = 7.0f;
  267.         break;
  268.     case CSeqFeatData::e_Prot:
  269.         glColor4f(1.0f, 1.0f, 1.0f, 0.5f);
  270.         width = 9.0f;
  271.         break;
  272.     default:
  273.         break;
  274.     }
  275.     TSignedSeqPos s_from = loc.GetTotalRange().GetFrom();
  276.     TSignedSeqPos s_to   = loc.GetTotalRange().GetTo();
  277.     TSignedSeqPos al_from = m_DS->GetAlnMgr().GetAlnPosFromSeqPos
  278.         (idx, s_from);
  279.     TSignedSeqPos al_to   = m_DS->GetAlnMgr().GetAlnPosFromSeqPos
  280.         (idx, s_to);
  281.     if (al_from == -1) al_from = 0;
  282.     if (al_to   == -1) al_to   = m_AlnWidth;  // some times it happends            
  283.     al_from = al_from - m_ScrX;  // adjust with scroll values
  284.     al_to   = al_to   - m_ScrX + 1;
  285.     if (al_from < 0) al_from = 0;
  286.     GLfloat xx1 = al_from * kCellWidth;
  287.     GLfloat xx2 = al_to   * kCellWidth;
  288.     GLfloat yy  = GLfloat(row - m_ScrY) * kCellHeight + 
  289.         GLfloat(kCellHeight / 2);
  290.     x_DrawLine(xx1, yy, xx2, yy, width);
  291.     glDisable(GL_BLEND);
  292. }
  293. void CTextAlnPanel::x_DrawInsertions(TNumrow row, size_t idx) const
  294. {
  295.     glEnable(GL_BLEND);
  296.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  297.     glLineWidth(1.5f);
  298.     glEnable(GL_POLYGON_SMOOTH);
  299.     glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
  300.     CGlBitmapFont f(CGlBitmapFont::eHelvetica10);
  301.     GLfloat yy = GLfloat(row - m_ScrY) * kCellHeight;
  302.     CRef<CAlnMap::CAlnChunkVec> chunk_vec = m_DS->GetAlnMgr().GetAlnChunks
  303.         (idx, CAlnMap::TSignedRange(0, m_AlnWidth), 
  304.          CAlnVec::fInsertsOnly | CAlnVec::fIgnoreGaps);
  305.     string ins_str;
  306.     CGlColorTable table(chunk_vec->size(), 0.5f, 0.75f);
  307.     for (int i = 0;  i < chunk_vec->size();  i++) {  // for each chunk
  308.         CConstRef<CAlnMap::CAlnChunk> chunk = (*chunk_vec)[i];
  309.         TSeqPos seq_from = chunk->GetRange().GetFrom();
  310.         TSeqPos seq_to   = chunk->GetRange().GetTo();
  311.         TSeqPos aln_from = chunk->GetAlnRange().GetFrom();
  312.         m_DS->GetAlnMgr().GetSeqString(ins_str, idx, seq_from, seq_to);
  313.         string to_draw = x_PreprocessSeq(ins_str);
  314.         TSeqPos ins_len = ins_str.length();
  315.         GLfloat ww = gl_width(to_draw.c_str());
  316.         GLfloat xx = GLfloat((aln_from - m_ScrX - 1) * kCellWidth) - ww / 2.0f;
  317.         CGlColor color = table.GetColor(i);
  318.         glColor4f(color.GetRed(), color.GetGreen(), color.GetBlue(), 0.4f);
  319.         glBegin(GL_TRIANGLE_FAN);
  320.         glVertex2f(xx, yy);
  321.         glVertex2f(xx, yy + kCellHeight);
  322.         glVertex2f(xx + ww, yy + kCellHeight);
  323.         glVertex2f(xx + ww, yy);
  324.         glVertex2f(xx + ww / 2, yy - 6);
  325.         glEnd();
  326.         gl_color(FL_RED);  //m_SequenceColor); //  sequence
  327.         f.TextOut(xx, yy + kCellHeight, to_draw.c_str());
  328.         string label = NStr::UIntToString(ins_len);
  329.         ww = gl_width(label.c_str());
  330.         xx = GLfloat((aln_from - m_ScrX - 1) * kCellWidth) - ww / 2.0f;
  331.         gl_color(FL_BLACK);  // size
  332.         f.TextOut(xx, yy + kCellHeight / 2, label.c_str());
  333.     }
  334.     glLineWidth(1.0f);
  335.     glDisable(GL_BLEND);
  336.     glDisable(GL_POLYGON_SMOOTH);
  337. }
  338. void CTextAlnPanel::x_DrawTextPanel(void)
  339. {
  340.     x_ActivateViewPort(m_BP);
  341.     glMatrixMode(GL_MODELVIEW);
  342.     glLoadIdentity();
  343.     x_DrawGrid();
  344.     TNumrow startY  = m_ScrY;
  345.     TNumrow finishY = m_ScrY + m_Height / kCellHeight;
  346.     for (TNumrow row = startY; row != finishY && row < m_ParaG.size(); row++) {
  347.         CParaG para = m_ParaG[row];
  348.         switch(para.GetType()) {
  349.         case CParaG::eFeature:
  350.             x_DrawFeatures(row, para.GetIndex());
  351.             break;
  352.         case CParaG::eSequence:
  353.             x_DrawSequence(row, para.GetIndex());
  354.             break;
  355.         case CParaG::eInsertion:
  356.             x_DrawInsertions(row, para.GetIndex());
  357.             break;
  358.         }
  359.     }
  360.     glPopAttrib();
  361. }
  362. void CTextAlnPanel::x_DrawSeqNumPanel(void)
  363. {
  364.     x_ActivateViewPort(m_NP);    
  365.     x_DrawSelection(m_NP[3], eCol);
  366.     TSeqPos startX  = m_ScrX;
  367.     TSeqPos finishX = m_ScrX + m_NP[2] / kCellWidth;
  368.     TDim len = NStr::UIntToString(m_AlnWidth).length();
  369.     gl_color(m_GridColor);
  370.     glBegin(GL_LINES);
  371.     for (TSeqPos x = startX;  x != finishX;  x++) {
  372.         GLfloat xx = GLfloat(x - m_ScrX) * kCellWidth;
  373.         glVertex2f(xx, 0.0f);
  374.         glVertex2f(xx, m_NP[3]);
  375.     }
  376.     for (TNumrow y = 0;  y != len;  y++) {
  377.         GLfloat yy = y * kFontSize;
  378.         glVertex2f(0.0f,    yy);
  379.         glVertex2f(m_NP[2], yy);
  380.     }
  381.     glEnd();
  382.     gl_color(FL_GRAY);  // Draw thick separation line
  383.     x_DrawLine(0.0f, len * kFontSize + 1, m_NP[2], len * kFontSize + 1, 2.0f);
  384.     gl_color(m_NumbersColor);  // draw labels
  385.     CGlBitmapFont f(CGlBitmapFont::eHelvetica10);
  386.     for (TSeqPos x = startX;  x != finishX + 1;  x++) {
  387.         GLfloat xx = GLfloat(x - m_ScrX) * kCellWidth;
  388.         if (x % 10 == 0) {
  389.             string s = NStr::UIntToString(x);
  390.             int start = len - s.length();
  391.             for (TNumrow y = start, p = 0;  y!= len;  y++, p++) {
  392.                 string to_draw = s.substr(p, 1);
  393.                 GLfloat yy = y * kFontSize + kFontSize - 1;
  394.                 f.TextOut(xx + 2, yy, to_draw.c_str());
  395.             }
  396.         } else if (x % 5 == 0) {  // draw tick marks
  397.             x_DrawLine(xx + kCellWidth / 2,  m_NP[3] - 3 - kFontSize,
  398.                        xx + kCellWidth / 2, m_NP[3] - 3, 1.0f);
  399.         }
  400.     }
  401.     glPopAttrib();
  402. }
  403. void CTextAlnPanel::x_DrawLabelPanel(void)
  404. {
  405.     x_ActivateViewPort(m_LP);
  406.     x_DrawSelection(m_LP[2], eRow);
  407.     string label_draw;
  408.     for (TNumrow row = 0;  row != m_ParaG.size();  row++) {
  409.         if (m_ParaG[row].GetType() == CParaG::eFeature) {
  410.             string feat_label;
  411.             feature::GetLabel(m_ParaG[row].Feature()->GetFeature(), 
  412.                               &feat_label, feature::eBoth);
  413.             CGlBitmapFont f(CGlBitmapFont::eHelvetica10);
  414.             GLfloat yy = GLfloat(row - m_ScrY) * kCellHeight + kCellHeight - 3;
  415.             gl_color(m_SequenceColor);
  416.             f.TextOut(2, yy, feat_label.c_str());
  417.         }
  418.         if (m_ParaG[row].GetType() != CParaG::eSequence) continue;
  419.         GLfloat yy = GLfloat(row - m_ScrY + 1) * kCellHeight + 1;
  420.         if (m_Anchor == m_ParaG[row].GetIndex()) {  // draw anchor mark
  421.             x_DrawAnchorMark(row);
  422.         }
  423.         gl_color(m_NumbersColor);
  424.         const CSeq_id& id =
  425.             sequence::GetId(m_DS->GetAlnMgr().
  426.                             GetBioseqHandle(m_ParaG[row].GetIndex()),
  427.                             sequence::eGetId_Best);
  428.         id.GetLabel(&label_draw);
  429.         for (TSeqPos x = 0;  x != label_draw.length();  x++) {
  430.             GLfloat xx = kCellWidth + GLfloat(x * kCellWidth) + kCellWidth / 2;
  431.             string seq_this  = label_draw.substr(x, 1);
  432.             m_Font_8x13.TextOut(xx, yy - 2, seq_this.c_str());
  433.         }
  434.     }
  435.     gl_color(FL_GRAY);  // Draw thick separation line
  436.     x_DrawLine(m_LP[2] - 2, m_LP[1], m_LP[2] - 2, m_LP[3], 2.0f);
  437.     glPopAttrib();
  438. }
  439. void CTextAlnPanel::x_DrawAnchorMark(TNumrow row) const
  440. {
  441.     glEnable(GL_BLEND);
  442.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  443.     glEnable(GL_POLYGON_SMOOTH);
  444.     glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
  445.     gl_color(FL_GREEN);
  446.     GLfloat xx = kCellWidth / 2;
  447.     GLfloat yy = GLfloat(row - m_ScrY) * kCellHeight;
  448.     glBegin(GL_QUADS);
  449.     glVertex2f(xx ,              yy + kCellHeight / 2);
  450.     glVertex2f(xx + kCellWidth / 2, yy + kCellHeight);
  451.     glVertex2f(xx + kCellWidth , yy + kCellHeight / 2);
  452.     glVertex2f(xx + kCellWidth / 2, yy);
  453.     glEnd();
  454.     glDisable(GL_BLEND);
  455.     glDisable(GL_POLYGON_SMOOTH);
  456. }
  457. void CTextAlnPanel::x_DrawInfoPanel(void)
  458. {
  459.     x_ActivateViewPort(m_IP);
  460.     TDim len = NStr::UIntToString(m_AlnWidth).length();    
  461.     gl_color(FL_GRAY);  // Draw thick separation line
  462.     x_DrawLine(m_IP[2] - 2, 0.0f, m_IP[2] - 2, m_IP[3], 2.0f);
  463.     x_DrawLine(0.0f, len * kFontSize + 1, m_IP[2], len * kFontSize + 1, 2.0f);
  464.     glEnable(GL_BLEND);
  465.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  466.     glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
  467.     x_DrawLine(0.0f, 0.0f, m_IP[2], len * kFontSize + 1, 2.0f);
  468.     glDisable(GL_BLEND);
  469.     glDisable(GL_LINE_SMOOTH);
  470.     glLineWidth(1.0f);        
  471.     gl_color(m_NumbersColor);
  472.     CGlBitmapFont f(CGlBitmapFont::eHelvetica10);
  473.     f.TextOut(kCellWidth / 2, len * kFontSize - 2, kLabels.c_str());
  474.     GLfloat xx = m_IP[2] - gl_width(kPosition.c_str()) - kCellWidth;
  475.     f.TextOut(xx, kFontSize - 1, kPosition.c_str());
  476.     glPopAttrib();
  477. }
  478. void CTextAlnPanel::draw()
  479. {
  480.     if (!valid()) {
  481.         x_SetViewPorts    ();
  482.         x_AdjustScrollBars();
  483.     }
  484.     glClearColor(1, 1, 1, 0);
  485.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  486.     if ( !m_DS ) return;
  487.     x_DrawInfoPanel  ();
  488.     x_DrawSeqNumPanel();
  489.     x_DrawTextPanel ();
  490.     x_DrawLabelPanel ();
  491.     return;
  492. }
  493. void CTextAlnPanel::x_DrawLine(GLfloat x1, GLfloat y1, GLfloat x2,
  494.                                GLfloat y2, GLfloat width) const
  495. {
  496.     glLineWidth(width);
  497.     glBegin(GL_LINES);
  498.     glVertex2f(x1, y1);
  499.     glVertex2f(x2, y2);
  500.     glEnd();
  501.     glLineWidth(1.0f);
  502. }
  503. void CTextAlnPanel::x_SetViewPorts(void)
  504. {
  505.     m_Width  = w();
  506.     m_Height = h();
  507.     gl_font(FL_BOLD, kFontSize);
  508.     TDim m_NPHeight = gl_height() * 
  509.         NStr::UIntToString(m_AlnWidth).length();
  510.     TDim m_LPWidth = 0;
  511.     // find out the longest string
  512.     for (TNumrow row = 0;  row != m_AlnHeight;  row++) {
  513.         const CSeq_id& id =
  514.             sequence::GetId(m_DS->GetAlnMgr().GetBioseqHandle(row),
  515.                             sequence::eGetId_Best);
  516.         string str_label;
  517.         id.GetLabel(&str_label);
  518.         TDim len = str_label.length();
  519.         m_LPWidth = max(m_LPWidth, len);
  520.     }
  521.     m_LPWidth = (m_LPWidth + 2) * kCellWidth;  // add extra space
  522.     // Numbers panel (on top)
  523.     m_NP[0] = m_LPWidth;
  524.     m_NP[1] = m_Height - m_NPHeight;
  525.     m_NP[2] = m_Width - m_LPWidth;
  526.     m_NP[3] = m_NPHeight;
  527.     // Text panel
  528.     m_BP[0] = m_LPWidth;
  529.     m_BP[1] = 0;
  530.     m_BP[2] = m_Width  - m_LPWidth;
  531.     m_BP[3] = m_Height - m_NPHeight;
  532.     // Label panel (on the left)
  533.     m_LP[0] = 0;
  534.     m_LP[1] = 0;
  535.     m_LP[2] = m_LPWidth;
  536.     m_LP[3] = m_Height - m_NPHeight;
  537.     // Info panel (on the left/top corner)
  538.     m_IP[0] = 0;
  539.     m_IP[1] = m_Height - m_NPHeight;
  540.     m_IP[2] = m_LPWidth;
  541.     m_IP[3] = m_NPHeight;
  542. }
  543. void CTextAlnPanel::x_AdjustScrollBars(void)
  544. {
  545.     Fl_Scrollbar* scrollX = (Fl_Scrollbar*)(parent()->child(0));
  546.     Fl_Scrollbar* scrollY = (Fl_Scrollbar*)(parent()->child(1));
  547.     scrollX->linesize(1);
  548.     scrollY->linesize(1);
  549.     scrollX->value(m_ScrX, m_BP[2] / kCellWidth, 0, m_AlnWidth + 1);
  550.     if (m_AlnWidth * kCellWidth < m_BP[2]) scrollX->hide();
  551.     else scrollX->show();
  552.     scrollY->value(m_ScrY, m_BP[3] / kCellHeight, 0, m_ParaG.size());
  553.     if (m_ParaG.size() * kCellHeight < m_BP[3]) scrollY->hide();
  554.     else scrollY->show();
  555. }
  556. string CTextAlnPanel::x_PreprocessSeq(const string& s) const
  557. {
  558.     if (s.length() <= 10) {
  559.         return s;
  560.     } else {
  561.         return s.substr(0, 4) + "..." + s.substr(s.length() - 5, 4);
  562.     }
  563. }
  564. void CTextAlnPanel::x_ActivateViewPort(GLuint* port) const
  565. {
  566.     glPushAttrib(GL_VIEWPORT_BIT);
  567.     glShadeModel(GL_FLAT);
  568.     glViewport(port[0], port[1], port[2], port[3]);
  569.     glMatrixMode(GL_PROJECTION);
  570.     glLoadIdentity();
  571.     glOrtho(0, port[2], port[3], 0, -1, 1);
  572.     glMatrixMode(GL_MODELVIEW);
  573.     glLoadIdentity();
  574. }
  575. int CTextAlnPanel::handle(int event)
  576. {
  577.     static int  s_X, s_Y;
  578.     static bool s_Drag;
  579.     switch (event) {        
  580.     case FL_PUSH:
  581.         s_X = Fl::event_x();
  582.         s_Y = Fl::event_y();
  583.         s_Drag = false;
  584.         return 1;
  585.     case FL_DRAG:
  586.         s_Drag = true;
  587.         if (Fl::event_shift()) {
  588.             int pos = Fl::event_x() + m_ScrX * kCellWidth - m_LP[2];
  589.             size_t x = pos / kCellWidth;
  590.             if ( pos < 0  ||  x < 0  ||  x >= m_AlnWidth) return 1;
  591.             m_ColSelect[x] = !Fl::event_ctrl();
  592.             redraw();
  593.         } else {
  594.             size_t idx = x_GetAtXY(Fl::event_x(), Fl::event_y());
  595.             if (idx != kUnknowIdx) {
  596.                 m_RowSelect[idx] = !Fl::event_ctrl();
  597.                 redraw();
  598.             }
  599.         }
  600.         return 1;
  601.     case FL_RELEASE:
  602.         if (s_Drag) {
  603.             s_Drag   = false;
  604.         } else  {
  605.             size_t idx = x_GetAtXY(Fl::event_x(), Fl::event_y());
  606.             if (idx != kUnknowIdx) {
  607.                 m_RowSelect[idx] = !Fl::event_ctrl();
  608.                 redraw();
  609.             }
  610.         }
  611.         return 1;
  612.     default:
  613.         return Fl_Gl_Window::handle(event);
  614.     }
  615.     return 0;
  616. }
  617. size_t CTextAlnPanel::x_GetAtXY(int x, int y) const
  618. {
  619.     int pos = y + m_ScrY * kCellHeight - m_NP[3];
  620.     //if (pos < 0) return kUnknowIdx;
  621.     size_t idx = pos / kCellHeight;
  622.     if ( pos < 0  ||  idx >= m_ParaG.size()) return kUnknowIdx;
  623.     else return m_ParaG[idx].GetIndex();
  624. }
  625. // --- Scrolling --------------------------------------------------
  626. void CTextAlnPanel::Scroll(TSeqPos xPos, TSeqPos yPos)
  627. {
  628.     m_ScrX = xPos;
  629.     m_ScrY = yPos;
  630.     redraw();
  631. }
  632. void CTextAlnPanel::SetFeatureDisplay(CTextAlnView::EFeatureDisplay disp)
  633. {
  634.     if ( !m_DS ) return;
  635.     m_featDisp = disp;
  636.     x_PrepareData();
  637.     invalidate();
  638.     redraw();
  639. }
  640. // Colors
  641. void CTextAlnPanel::SetColor(CTextAlnView::EDisplayElement elem, 
  642.                              Fl_Color color)
  643. {
  644.     switch (elem) {
  645.     case CTextAlnView::eBackground: { m_BackgroundColor = color; break; }
  646.     case CTextAlnView::eGrid:       { m_GridColor       = color; break; }
  647.     case CTextAlnView::eNumbers:    { m_NumbersColor    = color; break; }
  648.     case CTextAlnView::eSelection:  { m_SelectionColor  = color; break; }
  649.     case CTextAlnView::eSequence:   { m_SequenceColor   = color; break; }
  650.     case CTextAlnView::eMismatch:   { m_MismatchColor   = color; break; }
  651.     }
  652.     redraw();
  653. }
  654. Fl_Color CTextAlnPanel::GetColor(CTextAlnView::EDisplayElement elem) const
  655. {
  656.     switch (elem) {
  657.     case CTextAlnView::eBackground: return m_BackgroundColor;
  658.     case CTextAlnView::eGrid:       return m_GridColor;
  659.     case CTextAlnView::eNumbers:    return m_NumbersColor;
  660.     case CTextAlnView::eSelection:  return m_SelectionColor;
  661.     case CTextAlnView::eSequence:   return m_SequenceColor;
  662.     case CTextAlnView::eMismatch:   return m_MismatchColor;
  663.     }
  664.     return FL_BLACK;
  665. }
  666. END_NCBI_SCOPE
  667. /*
  668.  * ===========================================================================
  669.  * $Log: textaln_panel.cpp,v $
  670.  * Revision 1000.2  2004/06/01 21:08:00  gouriano
  671.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.12
  672.  *
  673.  * Revision 1.12  2004/05/21 22:27:52  gorelenk
  674.  * Added PCH ncbi_pch.hpp
  675.  *
  676.  * Revision 1.11  2004/03/11 17:50:41  dicuccio
  677.  * Updated typedefs: dropped TDimension, TPosition, TIndex, TColor; use TSeqRange
  678.  * instead of TRange
  679.  *
  680.  * Revision 1.10  2004/03/05 17:39:13  dicuccio
  681.  * Use sequence::Getid() instead of CSeq_id::GetStringDescr()
  682.  *
  683.  * Revision 1.9  2003/09/29 15:49:58  dicuccio
  684.  * Use CGlBitmapFont instead of home-grown font.
  685.  *
  686.  * Revision 1.8  2003/09/24 19:24:41  ucko
  687.  * ~CTextAlnPanel: stop explicitly deleting m_DS, which is now a CRef.
  688.  *
  689.  * Revision 1.7  2003/09/24 18:34:58  dicuccio
  690.  * Use new generic alignment data source.  Removed USING_SCOPE(objects) from
  691.  * headers; used objects:: where necessary
  692.  *
  693.  * Revision 1.6  2003/09/17 16:29:03  dicuccio
  694.  * Use CGlBitmapFont instead of CGlutFont
  695.  *
  696.  * Revision 1.5  2003/08/18 15:23:40  lebedev
  697.  * Changed nales: CFeature -> CLayoutFeat
  698.  *
  699.  * Revision 1.4  2003/07/21 20:28:27  dicuccio
  700.  * Fixed creation of CFeature to match new API
  701.  *
  702.  * Revision 1.3  2003/06/02 16:06:27  dicuccio
  703.  * Rearranged src/objects/ subtree.  This includes the following shifts:
  704.  *     - src/objects/asn2asn --> arc/app/asn2asn
  705.  *     - src/objects/testmedline --> src/objects/ncbimime/test
  706.  *     - src/objects/objmgr --> src/objmgr
  707.  *     - src/objects/util --> src/objmgr/util
  708.  *     - src/objects/alnmgr --> src/objtools/alnmgr
  709.  *     - src/objects/flat --> src/objtools/flat
  710.  *     - src/objects/validator --> src/objtools/validator
  711.  *     - src/objects/cddalignview --> src/objtools/cddalignview
  712.  * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  713.  * replaces the three libmmdb? libs.
  714.  *
  715.  * Revision 1.2  2003/03/27 20:38:57  dicuccio
  716.  * Fixed compilation errors under Linux (gcc-3.0.4)
  717.  *
  718.  * Revision 1.1  2003/03/27 17:04:32  lebedev
  719.  * Text Alignment Widget: Initial revision
  720.  *
  721.  * ===========================================================================
  722.  */