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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: align_mark_handler.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 21:06:57  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: align_mark_handler.cpp,v 1000.3 2004/06/01 21:06:57 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:  Andrey Yazhuk
  35.  *
  36.  * File Description:
  37.  * CAlignMarkHandler - class implementing support for Marks in alignments.
  38.  * IAlignMarkHandlerHost - context in which CAlignMarkHandler operates.
  39.  */
  40. #include <ncbi_pch.hpp>
  41. #include <FL/Fl.H>
  42. #include <FL/Enumerations.H>
  43. #include <gui/widgets/aln_multiple/align_mark_handler.hpp>
  44. #include <gui/widgets/aln_multiple/alnmulti_settings.hpp>
  45. #include <math.h>
  46. BEGIN_NCBI_SCOPE
  47. USING_SCOPE(objects);
  48. CAlignMarkHandler::CAlignMarkHandler()
  49. : m_pHost(NULL),
  50.     m_pPane(NULL),
  51.     m_bHitResizable(false),
  52.     m_State(eIdle),
  53.     m_Cursor(FL_CURSOR_DEFAULT),
  54.     m_PrevPos((TSeqPos)-1),
  55.     m_FillColor(0.5f, 0.5f, 1.0f, 0.5f),
  56.     m_FrameColor(0.25f, 0.25f, 0.5f, 1.0f)        
  57. {    
  58. }
  59. void    CAlignMarkHandler::SetHost(IAlignMarkHandlerHost* pHost)
  60. {
  61.     m_pHost = pHost;
  62. }
  63. //FLTK-like event handler
  64. int CAlignMarkHandler::handle(CGUIEvent& event, CGlPane& pane)
  65. {
  66.     m_pPane = &pane;
  67.     int res = 0;
  68.     switch(event.GetFLTKEvent())   {
  69.     case FL_PUSH: res =  x_OnMousePush(event); break;
  70.     case FL_DRAG: res =  x_OnMouseDrag(event); break;
  71.     case FL_RELEASE: res =  x_OnMouseRelease(event); break;
  72.     case FL_MOVE: res =  x_OnMouseMove(event); break;
  73.     case FL_KEYDOWN: res =  x_OnKeyDown(event); break;
  74.     case FL_KEYUP: res =  x_OnKeyUp(event); break;
  75.     }
  76.     m_pPane = 0;
  77.     return res;
  78. }
  79. ////////////////////////////////////////////////////////////////////////////////
  80. // opeartions with Mark
  81. void    CAlignMarkHandler::MarkSelectedRows(const TRangeColl& C, bool bMark)
  82. {
  83.     const TSelListModel* pModel = x_GetHost()->MHH_GetSelListModel();
  84.     TSelListModel::TIndexVector vSel;
  85.     pModel->SLM_GetSelectedIndices(vSel);
  86.     const IAlnMultiDataSource*  pAlnDS = x_GetHost()->MHH_GetAlnDS();
  87.     
  88.     ITERATE(TSelListModel::TIndexVector, it, vSel)  { // for each Mark
  89.         TNumrow Row = pModel->SLM_GetItem(*it);
  90.         
  91.         TRowToMarkMap::iterator itM = m_mpRowToMark.find(Row);
  92.         if(itM == m_mpRowToMark.end()) 
  93.             itM = m_mpRowToMark.insert(TRowToMarkMap::value_type(Row, TRangeColl())).first;
  94.                 
  95.         TRangeColl& Mark = itM->second;
  96.         
  97.         ITERATE(TRangeColl, itR, C) { // for each Range in C
  98.             // translate Range to sequence coordinates
  99.             TSeqPos From = 
  100.                 pAlnDS->GetSeqPosFromAlnPos(Row, itR->GetFrom(),
  101.                                             IAlnMultiDataSource::
  102.                                             TSearchDirection::eRight);
  103.             TSeqPos To =
  104.                 pAlnDS->GetSeqPosFromAlnPos(Row, itR->GetTo(),
  105.                                             IAlnMultiDataSource::
  106.                                             TSearchDirection::eRight);
  107.             TSeqRange  R(From, To);    
  108.             // modify Mark
  109.             if(bMark)
  110.                     Mark += R;
  111.             else    Mark -= R;
  112.         }
  113.     }
  114. }
  115. void    CAlignMarkHandler::UnMarkAll()
  116. {
  117.     m_mpRowToMark.clear();
  118. }
  119. void    CAlignMarkHandler::UnMarkSelected()
  120. {
  121.     // get selected lines
  122.     const TSelListModel* pModel = x_GetHost()->MHH_GetSelListModel();
  123.     TSelListModel::TIndexVector vIndices;
  124.     pModel->SLM_GetSelectedIndices(vIndices);
  125.         
  126.     // for each selected Line
  127.     ITERATE(TSelListModel::TIndexVector, it, vIndices)  {
  128.         TNumrow Row = x_GetHost()->MHH_GetRowByLine(*it);        
  129.         m_mpRowToMark.erase(Row);
  130.     }
  131. }
  132. const   CAlignMarkHandler::TRowToMarkMap&  CAlignMarkHandler::GetMarks() const
  133. {
  134.     return m_mpRowToMark;
  135. }
  136. ////////////////////////////////////////////////////////////////////////////////
  137. // event handlers
  138. int CAlignMarkHandler::x_OnMousePush(CGUIEvent& event)
  139. {    
  140.     if(event.GetGUIState() == CGUIEvent::eMarkState  &&
  141.         event.GetGUISignal() == CGUIEvent::ePush) {  
  142.         if(Fl::event_clicks() == 0) {
  143.             x_OnStartSel();
  144.             x_OnSelectCursor();
  145.         }                
  146.         return 1;
  147.     }
  148.     return 0;
  149. }
  150. int CAlignMarkHandler::x_OnMouseDrag(CGUIEvent& event)
  151. {
  152.     if(m_State == eResize  &&  event.GetGUIState() == CGUIEvent::eMarkState) {
  153.         x_OnChangeSelRange();
  154.     }
  155.     return 1; // always handle drags
  156. }
  157. int CAlignMarkHandler::x_OnMouseRelease(CGUIEvent& event)
  158. {
  159.     if(m_State != eIdle)    {
  160.         if(event.GetGUISignal() == CGUIEvent::eRelease)    {
  161.             if(m_State == eResize)  { 
  162.                 bool b_mark = (event.GetGUIState() == CGUIEvent::eMarkState);
  163.                 EState new_state = b_mark ? eReady : eIdle;
  164.                                     
  165.                 x_OnEndSelRange(new_state);
  166.             }
  167.             return 1;
  168.         }
  169.     }
  170.     return 0;
  171. }
  172. int CAlignMarkHandler::x_OnMouseMove(CGUIEvent& event)
  173. {
  174.     //if(x_OpKeyPressed()) {
  175.     if(event.GetGUIState() == CGUIEvent::eMarkState)    {
  176.         x_OnSelectCursor();
  177.         return 1;
  178.     } else return 0;
  179. }
  180. int CAlignMarkHandler::x_OnKeyDown(CGUIEvent& event)
  181. {
  182.     if(event.GetGUIState() == CGUIEvent::eMarkState)    {
  183.         int k = Fl::event_key();    
  184.         if(k == FL_Delete)  {
  185.             UnMarkSelected();
  186.             x_GetHost()->MHH_Redraw();
  187.             return 1;
  188.         }
  189.         x_UpdateState(true);        
  190.     }
  191.     return 0;
  192. }
  193. int CAlignMarkHandler::x_OnKeyUp(CGUIEvent& event)
  194. {
  195.     //int k = Fl::event_key();
  196.     //if(k == FL_Control_L  ||  k == FL_Control_R)    { //Control is released
  197.     if(m_State == eResize)   { 
  198.         if(event.GetGUIState() != CGUIEvent::eMarkState)    {
  199.             EState new_state = (event.GetGUIState() == CGUIEvent::eMarkState) ? eReady : eIdle;
  200.             x_OnEndSelRange(new_state);
  201.         } else    x_UpdateState(true);
  202.     }    
  203.     return 0;
  204. }
  205. ////////////////////////////////////////////////////////////////////////////////
  206. /// Signal handlers
  207. void    CAlignMarkHandler::x_OnStartSel()
  208. {    
  209.     if(x_HitSelectedLine()) {
  210.         m_PrevPos = (TSeqPos) -1;
  211.         x_InitDeltaMap();
  212.         m_State = eResize; 
  213.         m_pHost->MHH_Redraw();
  214.     }
  215. }
  216. void    CAlignMarkHandler::x_OnChangeSelRange()
  217. {    
  218.     TModelUnit mX = x_MouseToSeqPos();
  219.     TSeqPos Pos = (TSeqPos) floor(mX);
  220.     Pos = x_ClipPosByRange(Pos);
  221.     if(Pos != m_PrevPos)    {
  222.         x_UpdateSelection(Pos);
  223.         m_pHost->MHH_Redraw();
  224.     }
  225.     m_PrevPos = Pos;
  226. }
  227. void    CAlignMarkHandler::x_OnEndSelRange(EState new_state)
  228. {
  229.     x_OnChangeSelRange();            
  230.             
  231.     x_UpdateMarks();
  232.     //m_State = x_OpKeyPressed() ? eReady : eIdle;
  233.     m_State = new_state;
  234.     x_OnSelectCursor();
  235.     m_pHost->MHH_Redraw();    
  236. }
  237. void    CAlignMarkHandler::x_OnResetAll()
  238. {
  239.     m_mpRowToMark.clear();
  240.     m_mpRowToDelta.clear();
  241.     m_State = eIdle;
  242.     m_PrevPos = (TSeqPos) -1;
  243.     m_pHost->MHH_Redraw();
  244. }
  245. void    CAlignMarkHandler::x_UpdateState(bool b_key)
  246. {
  247.     //bool b_key = x_OpKeyPressed();
  248.     bool bHit = x_HitSelectedLine();
  249.     EState NewState = m_State;
  250.     switch(m_State) {
  251.     case    eIdle:  
  252.     case    eReady: NewState = (b_key  &&  bHit) ? eReady : eIdle;  break;
  253.     case    eResize:  NewState = b_key ? eResize : eIdle;  break;
  254.     }
  255.     if(NewState != m_State) {
  256.         m_State = NewState; 
  257.            
  258.         x_OnSelectCursor();
  259.         m_pHost->MHH_Redraw();
  260.     }    
  261. }
  262. // Select cursor depending on the current state and mouse position
  263. void    CAlignMarkHandler::x_OnSelectCursor()
  264. {
  265.     switch(m_State)    {
  266.     case eIdle:    m_Cursor = FL_CURSOR_DEFAULT; break;
  267.     case eReady:    {
  268.         if(x_HitSelectedLine()) {
  269.             m_Cursor = x_HitRangeBorder() ? FL_CURSOR_WE : FL_CURSOR_INSERT;
  270.         } else m_Cursor = FL_CURSOR_DEFAULT;
  271.     }; break;
  272.     case eResize:   m_Cursor = FL_CURSOR_WE; break;
  273.     default: break;
  274.     }   
  275.     fl_cursor(m_Cursor, FL_BLACK, FL_WHITE);
  276. }
  277. ////////////////////////////////////////////////////////////////////////////////
  278. /// helper functions
  279. // returns true if modifier Key assigned to the operations with Mark is pressed
  280. bool CAlignMarkHandler::x_OpKeyPressed()    const
  281. {
  282.     int ModState = Fl::event_state() & (FL_SHIFT | FL_ALT | FL_CTRL);
  283.     return ModState == FL_CTRL;
  284. }
  285. //returns true if no conflicting modifier keys are pressed
  286. bool CAlignMarkHandler::x_ModifiersOk()    const
  287. {
  288.     int State = Fl::event_state() & (FL_SHIFT | FL_ALT);
  289.     return State == 0;
  290. }
  291. // converts mouse X position to the position in Alignment
  292. TModelUnit CAlignMarkHandler::x_MouseToSeqPos()
  293. {
  294.     _ASSERT(m_pPane);
  295.     int x = Fl::event_x();
  296.     return m_pHost->MHH_GetSeqPosByX(x) + 0.5;
  297. }
  298. // functions creates a "Delta" map for ranges  that will be resized
  299. void    CAlignMarkHandler::x_InitDeltaMap()
  300. {
  301.     m_mpRowToDelta.clear();
  302.     int X = Fl::event_x();
  303.     // get selected lines
  304.     const TSelListModel* pModel = x_GetHost()->MHH_GetSelListModel();
  305.     TSelListModel::TIndexVector vIndices;
  306.     pModel->SLM_GetSelectedIndices(vIndices);
  307.     const IAlnMultiDataSource* pAlnDS = x_GetHost()->MHH_GetAlnDS();
  308.             
  309.     // for each selected Line
  310.     ITERATE(TSelListModel::TIndexVector, it, vIndices)  {
  311.         TNumrow Row = x_GetHost()->MHH_GetRowByLine(*it);
  312.         TSeqRange HitR;
  313.         
  314.         // hit testing Mark corresponding to the Row (if it exists)
  315.         bool bHitStart = false;
  316.         SMarkDelta::EExtState StartState, State;
  317.         TRowToMarkMap::iterator itM = m_mpRowToMark.find(Row);
  318.         if(itM != m_mpRowToMark.end())   {
  319.             TRangeColl& Mark = itM->second;
  320.             x_HitTest(Row, Mark, X, HitR, bHitStart);
  321.         } else { // if Mark does not exist - create it
  322. m_mpRowToMark[Row] = TRangeColl(); 
  323. }
  324.         
  325.         TSeqPos StartPos;
  326.         if(HitR.NotEmpty()) {   // hit a border of the marked range
  327.             StartState = State = bHitStart ? SMarkDelta::eExtRangeStart : SMarkDelta::eExtRangeEnd;
  328.             StartPos = bHitStart ? HitR.GetFrom() : HitR.GetToOpen();        
  329.         } else {        
  330.             StartState = SMarkDelta::eNoExt;
  331.             State = SMarkDelta::eExtRangeEnd;    
  332.             TModelUnit mX = x_MouseToSeqPos(); //###
  333.             StartPos = (TSeqPos) floor(mX);
  334.             StartPos = pAlnDS->GetSeqPosFromAlnPos(Row, StartPos,
  335.                                                    IAlnMultiDataSource::
  336.                                                    TSearchDirection::eRight);
  337.             HitR.SetFrom(StartPos);
  338.             HitR.SetLength(0);
  339.         }
  340.     
  341.     // initate Map record    
  342.         m_mpRowToDelta[Row] = SMarkDelta(HitR, TSeqRange(StartPos, StartPos - 1), StartState, State);        
  343.     }
  344. }
  345. //returns true if mouse pointer is over selected line
  346. bool    CAlignMarkHandler::x_HitSelectedLine()
  347. {
  348.     const TSelListModel* pModel = x_GetHost()->MHH_GetSelListModel();
  349.     int Y = Fl::event_y();
  350.     int Index = x_GetHost()->MHH_GetLineByWindowY(Y);
  351.     return Index >=0  &&  pModel->SLM_IsItemSelected(Index); 
  352. }
  353. // returns true if mouse pointer is located over the end of one of the marked segments
  354. bool    CAlignMarkHandler::x_HitRangeBorder() const
  355. {
  356.     int X = Fl::event_x();
  357.     int Y = Fl::event_y();
  358.     int Index = x_GetHost()->MHH_GetLineByWindowY(Y);
  359.     
  360.     if(Index >= 0)  {
  361.         const TSelListModel* pModel = x_GetHost()->MHH_GetSelListModel();
  362.        
  363.         if(pModel->SLM_IsItemSelected(Index))   { 
  364.             TNumrow Row = x_GetHost()->MHH_GetRowByLine(Index);
  365.             TSeqRange HitR;
  366.             bool bHitStart = false;
  367.             // test the Mark corresponding to the Row
  368.             TRowToMarkMap::const_iterator it = m_mpRowToMark.find(Row);
  369.             if(it != m_mpRowToMark.end())   {
  370.                 const TRangeColl& Mark = it->second;
  371.                 x_HitTest(Row, Mark, X, HitR, bHitStart);
  372.                 if(HitR.NotEmpty())
  373.                     return true;
  374.             }
  375.         }
  376.     }
  377.     return false;
  378. }
  379. // perfroms a hit test of a given position "X" agains given TRangeColl C
  380. // if positions hits a range in the C, this range is returned in "Range"
  381. // (in "sequence" coordinates), overwise "Range" is set empty. If position 
  382. // hits the start of a range then "bHitStart" is assigned "true"
  383. void    CAlignMarkHandler::x_HitTest(TNumrow Row, const TRangeColl& C, int X, TSeqRange& Range, bool& bHitStart) const
  384. {
  385.     _ASSERT(m_pPane);    
  386.     
  387.     int MinD = -1;
  388.     bool bMinStart = false;
  389.     TRangeColl::const_iterator itMinRange = C.end();
  390.     const IAlnMultiDataSource *pAlnDS = x_GetHost()->MHH_GetAlnDS();
  391.     ITERATE(TRangeColl, itR, C)  { // iterating by Ranges in C
  392.         TSeqPos From = pAlnDS->GetAlnPosFromSeqPos(Row, itR->GetFrom());
  393.         TSeqPos To = pAlnDS->GetAlnPosFromSeqPos(Row, itR->GetTo());
  394.         TSeqRange  AlnR(From, To);
  395.         int FromX = m_pPane->ProjectX(AlnR.GetFrom());
  396.         int ToX = m_pPane->ProjectX(AlnR.GetToOpen());
  397.         
  398.         int D = abs(X - FromX); // distance from the start of the range
  399.         if(MinD < 0 || MinD > D)    {
  400.             MinD = D;
  401.             bMinStart = true;
  402.             itMinRange = itR;
  403.         }
  404.         D = abs(X - ToX); // distance from the stop of the range
  405.         if(MinD > D)    {
  406.             MinD = D;
  407.             bMinStart = false;
  408.             itMinRange = itR;
  409.         }        
  410.     }
  411.     if(MinD > -1  && MinD <= CAlnMultiSettings::GetDragThreshold()) {
  412.         bHitStart = bMinStart;
  413.         _ASSERT(itMinRange != C.end());
  414.         Range  = *itMinRange;
  415.     } else Range.SetLength(0);
  416. }
  417. TSeqPos CAlignMarkHandler::x_ClipPosByRange(TSeqPos Pos)
  418. {
  419.     TModelRect rcL = m_pPane->GetModelLimitsRect();
  420.     Pos = min(Pos, (TSeqPos) rcL.Right() - 1);
  421.     Pos = max(Pos, (TSeqPos) rcL.Left());
  422.     return Pos;
  423. }
  424. // updates Ranges being dragged accordingly to the given position
  425. void    CAlignMarkHandler::x_UpdateSelection(TSeqPos Pos)
  426. {
  427.     const IAlnMultiDataSource* pAlnDS = x_GetHost()->MHH_GetAlnDS();
  428.     NON_CONST_ITERATE(TRowToDeltaMap, it, m_mpRowToDelta)    {
  429.         SMarkDelta& Delta = it->second;
  430.         TSeqPos SeqPos = pAlnDS->GetSeqPosFromAlnPos(it->first, Pos,
  431.                                                      IAlnMultiDataSource::
  432.                                                      TSearchDirection::eRight);
  433.         x_UpdateDelta(Delta.m_Range, Delta.m_State, SeqPos);
  434.     }
  435. }
  436. // update given range so that the range end specified by "State" becomes equal
  437. // to "Pos".
  438. void    CAlignMarkHandler::x_UpdateDelta(TSeqRange& R, 
  439.                                     SMarkDelta::EExtState& State, TSeqPos Pos)
  440. {
  441.     if(State == SMarkDelta::eNoExt  &&  Pos != R.GetFrom())   {
  442.         if(Pos > R.GetFrom()) {
  443.             R.SetToOpen(Pos);
  444.             State = SMarkDelta::eExtRangeEnd;
  445.         } else  {
  446.             R.SetToOpen(R.GetFrom());
  447.             R.SetFrom(Pos);
  448.             State = SMarkDelta::eExtRangeStart;
  449.         }
  450.     } else if(State == SMarkDelta::eExtRangeEnd &&  Pos != R.GetToOpen()) {
  451.         if(Pos > R.GetFrom())  { 
  452.             R.SetToOpen(Pos);
  453.         } else { //flip
  454.             R.SetToOpen(R.GetFrom());
  455.             R.SetFrom(Pos);
  456.             State = SMarkDelta::eExtRangeStart;
  457.         }
  458.     } else if(State == SMarkDelta::eExtRangeStart  &&  Pos != R.GetFrom())    {
  459.         if(Pos <= R.GetToOpen())  { 
  460.             R.SetFrom(Pos);
  461.         } else {
  462.             R.SetFrom(R.GetToOpen());
  463.             R.SetToOpen(Pos);
  464.             State = SMarkDelta::eExtRangeEnd;
  465.         }
  466.     }
  467. }
  468. void CAlignMarkHandler::x_UpdateMarks()
  469. {
  470.     ITERATE(TRowToDeltaMap, it, m_mpRowToDelta)    {
  471.         TNumrow Row = it->first;
  472.         TRowToMarkMap::iterator itMark = m_mpRowToMark.find(Row);
  473.         if(itMark == m_mpRowToMark.end())   {
  474.             itMark = m_mpRowToMark.insert(
  475.                         TRowToMarkMap::value_type(Row, TRangeColl())).first;
  476.         }
  477.         TRangeColl& C = itMark->second;
  478.         const SMarkDelta& Delta = it->second;    
  479.         const TSeqRange& R = Delta.m_Range;
  480.         const TSeqRange& HitR = Delta.m_HitRange;
  481.         
  482.         switch(Delta.m_StartState)  {
  483.         case SMarkDelta::eNoExt:    {
  484.             if(R.NotEmpty())
  485.                 C.CombineWith(R);
  486.         }; break;
  487.         case SMarkDelta::eExtRangeEnd:  {
  488.             if(R.GetTo() > HitR.GetTo())  {
  489.                 C.CombineWith(R);
  490.             } else {
  491.                 TSeqPos P = max(HitR.GetFrom(), R.GetFrom());
  492.                 C.Subtract(TSeqRange(P, HitR.GetTo()));
  493.                 if(R.GetFrom() < HitR.GetFrom())
  494.                     C.CombineWith(TSeqRange(R.GetFrom(), HitR.GetFrom() - 1));
  495.             }
  496.         }; break;
  497.         case SMarkDelta::eExtRangeStart:  {
  498.             if(R.GetFrom() < HitR.GetFrom())  {
  499.                 C.CombineWith(R);
  500.             } else {
  501.                 TSeqPos P = min(HitR.GetTo(), R.GetTo());
  502.                 C.Subtract(TSeqRange(HitR.GetFrom(), P));
  503.                 if(R.GetTo() > HitR.GetTo())
  504.                     C.CombineWith(TSeqRange(HitR.GetToOpen(), R.GetTo()));
  505.             }
  506.         }; break;
  507.         };
  508.     }
  509.     m_mpRowToDelta.clear();
  510. }
  511. void    CAlignMarkHandler::Render(CGlPane& pane)
  512. {
  513.     TModelRect rcV = pane.GetVisibleRect();
  514.     
  515.     const IAlnMultiDataSource* pAlnDS = x_GetHost()->MHH_GetAlnDS();
  516.     const TSelListModel* pModel = x_GetHost()->MHH_GetSelListModel();        
  517.  
  518.     if(! rcV.IsEmpty()  && pAlnDS  && pModel) {
  519.         TVPRect rcVP = pane.GetViewport();
  520.         pane.OpenOrtho();
  521.         TModelUnit offset_x = pane.GetOffsetX();
  522.         TModelUnit offset_y = pane.GetOffsetY();
  523.         
  524.         ITERATE(TRowToMarkMap, itM, m_mpRowToMark)  { // for each Mark
  525.             TNumrow Row = itM->first; 
  526.             int Index = x_GetHost()->MHH_GetLineByRowNum(Row);
  527.                             
  528.             if(Index >= 0)  { // row exists      
  529.                           
  530.                 TModelUnit top_y = x_GetHost()->MHH_GetLinePosY(Index);
  531.                 TModelUnit bottom_y = top_y + x_GetHost()->MHH_GetLineHeight(Index) - 1;
  532.                 bool bVisible = ! (bottom_y < rcV.Top()  ||  top_y > rcV.Bottom());
  533.                 
  534.                 if(bVisible) {
  535.                     bool bSelected = pModel->SLM_IsItemSelected(Index);
  536.                     const TRangeColl& Mark = itM->second;
  537.                     // draw existing mark
  538.                     ITERATE(TRangeColl, itR, Mark)  { // for each Range in Mark
  539.                         TSeqPos From = pAlnDS->
  540.                             GetAlnPosFromSeqPos(Row, itR->GetFrom(),
  541.                                                 IAlnMultiDataSource::
  542.                                                 TSearchDirection::eRight);
  543.                         TSeqPos To = pAlnDS->
  544.                             GetAlnPosFromSeqPos(Row, itR->GetTo(),
  545.                                                 IAlnMultiDataSource::
  546.                                                 TSearchDirection::eLeft);
  547.                         TSeqRange R(From ,To);
  548.                         glColorC(m_FillColor);
  549.                         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  550.                         glRectd(R.GetFrom() - offset_x, bottom_y - offset_y, 
  551.                                 R.GetToOpen() - offset_x, top_y - offset_y);
  552.                         
  553.                         if(bSelected)   {                            
  554.                             glColorC(m_FrameColor);
  555.                             glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  556.                             glRectd(R.GetFrom() - offset_x, bottom_y - offset_y, 
  557.                                     R.GetToOpen() - offset_x, top_y - offset_y);
  558.                         }
  559.                     }
  560.                     // draw Delta - range being edited
  561.                     TRowToDeltaMap::const_iterator itD = m_mpRowToDelta.find(Row);
  562.                     if(itD != m_mpRowToDelta.end())  {
  563.                         const SMarkDelta& Delta = itD->second;
  564.                         const TSeqRange& delta_R = Delta.m_Range;
  565.                         TSeqPos From = pAlnDS->
  566.                             GetAlnPosFromSeqPos(Row, delta_R.GetFrom(),
  567.                                                 IAlnMultiDataSource::
  568.                                                 TSearchDirection::eRight);
  569.                         TSeqPos To = pAlnDS->
  570.                             GetAlnPosFromSeqPos(Row, delta_R.GetTo(),
  571.                                                 IAlnMultiDataSource::
  572.                                                 TSearchDirection::eLeft);
  573.                         TSeqRange R(From ,To);
  574.                         glColor4d(0.25, 0.25, 1.0, 1.0);
  575.                         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  576.                         glRectd(R.GetFrom() - offset_x, bottom_y - offset_y, 
  577.                                 R.GetToOpen() - offset_x, top_y - offset_y);
  578.                     }
  579.                 }
  580.             }
  581.         }
  582.         pane.Close();
  583.     }
  584. }
  585. END_NCBI_SCOPE
  586. /*
  587.  * ===========================================================================
  588.  * $Log: align_mark_handler.cpp,v $
  589.  * Revision 1000.3  2004/06/01 21:06:57  gouriano
  590.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17
  591.  *
  592.  * Revision 1.17  2004/05/21 22:27:52  gorelenk
  593.  * Added PCH ncbi_pch.hpp
  594.  *
  595.  * Revision 1.16  2004/04/02 17:09:40  yazhuk
  596.  * Updated function calls to renamed function
  597.  *
  598.  * Revision 1.15  2004/03/11 17:50:41  dicuccio
  599.  * Updated typedefs: dropped TDimension, TPosition, TIndex, TColor; use TSeqRange
  600.  * instead of TRange
  601.  *
  602.  * Revision 1.14  2003/12/18 21:13:08  yazhuk
  603.  * Updated code to supported template ISelListModel
  604.  *
  605.  * Revision 1.13  2003/12/10 17:11:38  yazhuk
  606.  * Clean-up.
  607.  *
  608.  * Revision 1.12  2003/12/08 15:15:55  yazhuk
  609.  * Implemented workaround for OpenGL precision problems.
  610.  *
  611.  * Revision 1.11  2003/12/05 17:51:57  yazhuk
  612.  * Disabled traces
  613.  *
  614.  * Revision 1.10  2003/12/01 16:43:18  yazhuk
  615.  * Refactored event handling - introduced CGUIEvent
  616.  *
  617.  * Revision 1.9  2003/11/26 16:52:00  johnson
  618.  * switch IAlnMultiDataSource to use CAlnMap::ESearchDirection instead of it's
  619.  * own ESearchDirection
  620.  *
  621.  * Revision 1.8  2003/10/29 23:23:25  yazhuk
  622.  * Replaced CAlnMultiDataSource with IAlignMultiDataSource
  623.  *
  624.  * Revision 1.7  2003/10/20 15:47:31  yazhuk
  625.  * Changed keyboard events handling policy. Clean-up.
  626.  *
  627.  * Revision 1.6  2003/10/15 21:27:19  yazhuk
  628.  * Migrated from using CAlnVec to accessing data via "generic" interface in CAlignDataSource.
  629.  *
  630.  * Revision 1.5  2003/10/12 16:28:40  ucko
  631.  * Properly capitalize (and <delimit>, while I'm at it) FLTK headers
  632.  *
  633.  * Revision 1.4  2003/09/29 13:45:49  yazhuk
  634.  * Added GetMarks()
  635.  *
  636.  * Revision 1.3  2003/09/25 20:47:10  yazhuk
  637.  * Fixed problem with displaying marks over inserts
  638.  *
  639.  * Revision 1.2  2003/09/24 02:52:54  ucko
  640.  * Add missing include of <math.h>
  641.  *
  642.  * Revision 1.1  2003/09/23 21:18:25  yazhuk
  643.  * Initial revision
  644.  *
  645.  * ===========================================================================
  646.  */