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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: hit_matrix_graph.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 21:10:56  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.11
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: hit_matrix_graph.cpp,v 1000.3 2004/06/01 21:10:56 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.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbistl.hpp>
  41. #include <gui/opengl/glhelpers.hpp>
  42. #include <gui/graph/igraph_utils.hpp>
  43. #include <gui/widgets/hit_matrix/hit_matrix_graph.hpp>
  44. #include <FL/Fl.H>
  45. #include <math.h>
  46. BEGIN_NCBI_SCOPE
  47. CHitElemGlyph::CHitElemGlyph()
  48. :   m_ColorIndex(-1),
  49.     m_bSelected(false)
  50. {
  51. }
  52. CHitElemGlyph::CHitElemGlyph(const CHitElemDataAdapter& hit_elem)
  53. :   m_HitElem(hit_elem),
  54.     m_ColorIndex(-1),
  55.     m_bSelected(false)
  56. {
  57. }
  58. void    CHitElemGlyph::GetModelRect(TModelRect& rc) const
  59. {
  60.     rc.Init(m_HitElem.GetSubjectStart(), m_HitElem.GetQueryStart());
  61.     TSeqPos size = 1 + m_HitElem.GetLength();
  62.     rc.SetSize(size, size);
  63. }
  64. void    CHitElemGlyph::Render(CGlPane& pane, ERenderingPass what)
  65. {
  66.     TModelUnit x1 = 0.5 + m_HitElem.GetSubjectStart();
  67.     TModelUnit y1 = 0.5 + m_HitElem.GetQueryStart();
  68.     TModelUnit l = m_HitElem.GetLength();
  69.     TModelUnit x2 = x1 + l;
  70.     TModelUnit y2 = y1 + l;
  71.     switch(what)    { 
  72.     case eEndPoints:   
  73.     case eHitElemLines:    {
  74.         glVertex2d(x1, y1);
  75.         glVertex2d(x2, y2);
  76.     }; break;
  77.     case eProjLines:    {        
  78.         TModelUnit left = min(x1, pane.GetVisibleRect().Left());
  79.         TModelUnit bottom = min(y1, pane.GetVisibleRect().Bottom());
  80.         glVertex2d(x1, y1);
  81.         glVertex2d(left, y1);
  82.         
  83.         glVertex2d(left, y2);
  84.         glVertex2d(x2, y2);       
  85.         glVertex2d(x1, y1);
  86.         glVertex2d(x1, bottom);
  87.         
  88.         glVertex2d(x2, bottom);
  89.         glVertex2d(x2, y2);        
  90.     }; break;
  91.     default: break;
  92.     }
  93. }
  94. void    CHitElemGlyph::StartVertex()
  95. {
  96.     TModelUnit x1 = 0.5 + m_HitElem.GetSubjectStart();
  97.     TModelUnit y1 = 0.5 + m_HitElem.GetQueryStart();    
  98.     glVertex2d(x1, y1);
  99. }
  100. void    CHitElemGlyph::EndVertex()
  101. {
  102.     TModelUnit l = m_HitElem.GetLength();
  103.     TModelUnit x1 = 0.5 + m_HitElem.GetSubjectStart() + l;
  104.     TModelUnit y1 = 0.5 + m_HitElem.GetQueryStart() + l;    
  105.     glVertex2d(x1, y1);
  106. }
  107. inline double square(double x)  {    return pow(x, 2);  }
  108. double  CHitElemGlyph::GetDistPixels(CGlPane& pane, const TVPPoint& pt) const
  109. {    
  110.     TModelUnit x1 = 0.5 + m_HitElem.GetSubjectStart();
  111.     TModelUnit y1 = 0.5 + m_HitElem.GetQueryStart();
  112.     TVPPoint p1 = pane.Project(x1, y1);
  113.  
  114.     TModelUnit l = m_HitElem.GetLength();
  115.     TModelUnit x2 = x1 + l;
  116.     TModelUnit y2 = y1 + l;
  117.     TVPPoint p2 = pane.Project(x2, y2);
  118.     double alpha = atan2((double)(p2.Y() - p1.Y()), (double)(p2.X() - p1.X()));
  119.     double max_proj = sqrt( square(p2.Y() - p1.Y()) + square(p2.X() - p1.X()));
  120.     double beta = atan2((double)(pt.Y() - p1.Y()), (double)(pt.X() - p1.X()));
  121.     double hyp = sqrt( square(pt.Y() - p1.Y()) + square(pt.X() - p1.X()));
  122.     double angle = beta - alpha;
  123.     
  124.     double proj = hyp * cos(angle);
  125.     if(proj >= 0  &&  proj <= max_proj)  { // projection point is on hit
  126.         double ortho_d = fabs( hyp * sin(angle));
  127.         return ortho_d;
  128.     } else { // calculate min of distances to hit's ends
  129.         double d2 = sqrt( square(pt.Y() - p2.Y()) + square(pt.X() - p2.X()));
  130.         return min(hyp, d2);
  131.     }
  132. }
  133. bool  CHitElemGlyph::InRect(CGlPane& pane, const TVPRect& rc) const
  134. {    
  135.     TModelUnit x1 = 0.5 + m_HitElem.GetSubjectStart();
  136.     TModelUnit y1 = 0.5 + m_HitElem.GetQueryStart();
  137.     TVPPoint p1 = pane.Project(x1, y1);
  138.     
  139.     if(rc.PtInRect(p1)) {
  140.         TModelUnit l = m_HitElem.GetLength();
  141.         TModelUnit x2 = x1 + l;
  142.         TModelUnit y2 = y1 + l;
  143.         TVPPoint p2 = pane.Project(x2, y2);
  144.         return rc.PtInRect(p2);
  145.     }
  146.     return false;
  147. }
  148. ///////////////////////////////////////////////////////////////////////////////
  149. /// CHitGlyph
  150. CHitGlyph::CHitGlyph(const CHitDataAdapter* p_hit)
  151. : m_pHit(p_hit)
  152. {
  153.     _ASSERT(m_pHit);
  154.     // create Elem glyphs
  155.     size_t size = p_hit->GetElemsCount();
  156.     m_Elems.reserve(size);
  157.     
  158.     for( size_t i = 0; i < size;  i++ ) {
  159.         CHitElemDataAdapter elem = p_hit->GetElem(i);
  160.         if(elem.GetQueryStart() >=0  && elem.GetSubjectStart() >= 0 )   { 
  161.             // not gap - create glyph
  162.             m_Elems.push_back(CHitElemGlyph(elem));
  163.         }
  164.     }
  165. }
  166. CHitGlyph::TElemGlyphCont&  CHitGlyph::GetElems()
  167. {
  168.     return m_Elems;
  169. }
  170. void    CHitGlyph::SetColorIndex(int index)
  171. {
  172.     NON_CONST_ITERATE(TElemGlyphCont, it, m_Elems)  {
  173.         it->SetColorIndex(index);
  174.     }
  175. }
  176. void    CHitGlyph::Render(CGlPane& pane, CHitElemGlyph::ERenderingPass what)
  177. {    
  178.     int size = m_Elems.size();    
  179.     switch(what)    {
  180.     case CHitElemGlyph::eConnectionLines:   {                
  181.         for( int i = 0; i < size - 1; )   {
  182.             m_Elems[i].EndVertex();
  183.             m_Elems[++i].StartVertex();
  184.         }
  185.     }; break;
  186.     default:    {
  187.         for( int i = 0; i < size; i++ )   {
  188.             m_Elems[i].Render(pane, what);
  189.         }
  190.     }; //default        
  191.     }// switch
  192. }
  193. ///////////////////////////////////////////////////////////////////////////////
  194. /// CHitMatrixGraph
  195. static float    kHitAlpha = 1.0;
  196. CHitMatrixGraph::CHitMatrixGraph()
  197. :   m_DefaultColor(0.25f, 0.25f, 0.25f, kHitAlpha),
  198.     m_SelColor(0.5f, 0.5f, 1.0f, 1.0f),
  199.     m_HighLightColor(0.8f, 0.8f, 1.0f, 0.5),
  200.     m_PathColor(0.2f, 0.2f, 0.2f, 1.0f),
  201.     m_ProjLinesColor(0.8f, 0.8f, 1.0f, 0.25f),
  202.     m_ProjBackColor(0.8f, 0.8f, 1.0f, 0.25f),
  203.     m_pHost(NULL),
  204.     m_pPane(NULL),
  205.     m_State(eIdle)
  206. {
  207.     CreateColorTable(32);
  208. }
  209. CHitMatrixGraph::~CHitMatrixGraph()
  210. {
  211.     DeleteGlyphs();
  212. }
  213. void    CHitMatrixGraph::DeleteGlyphs()
  214. {
  215.     destroy_and_erase_elems(m_vGlyphs);
  216. }
  217. void    CHitMatrixGraph::CreateGlyph(const CHitDataAdapter* p_hit_elem)
  218. {
  219.     m_vGlyphs.push_back(new CHitGlyph(p_hit_elem));
  220. }
  221. void    CHitMatrixGraph::Render(CGlPane& pane)
  222. {
  223.     pane.OpenOrtho();
  224.     x_RenderPath(pane);    
  225.     x_RenderSelection(pane);
  226.     x_RenderHits(pane);
  227.     
  228.     pane.Close();
  229.     x_RenderEventHandler(pane);
  230. }
  231. void    CHitMatrixGraph::x_RenderHits(CGlPane& pane)
  232. {
  233.     glEnable(GL_BLEND);
  234.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  235.     
  236.     glEnable(GL_LINE_SMOOTH);
  237.     glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);   
  238.     
  239.     // draw Hit Element Lines  
  240.     glColorC(x_GetColorByIndex(m_CurrColorIndex));
  241.     
  242.     glLineWidth(1.5f);
  243.     glBegin(GL_LINES);                
  244.         NON_CONST_ITERATE(THitGlyphVector, it, m_vGlyphs)    { // for each Hit
  245.             CHitGlyph::TElemGlyphCont& elems = (*it)->GetElems();
  246.             // for each Hit Element
  247.             NON_CONST_ITERATE(CHitGlyph::TElemGlyphCont, itE, elems)    {
  248.               if(itE->IsSelected()) {
  249.                 glColorC(m_SelColor);
  250.                 m_CurrColorIndex = -2;
  251.                 } else {
  252.                     int ind = itE->GetColorIndex();
  253.                     if(ind != m_CurrColorIndex) {
  254.                         m_CurrColorIndex = ind;
  255.                         glColorC(x_GetColorByIndex(m_CurrColorIndex));
  256.                     }
  257.                 }
  258.                 itE->Render(pane, CHitElemGlyph::eHitElemLines);
  259.             }
  260.         }    
  261.     glEnd();
  262.     glDisable(GL_LINE_SMOOTH);
  263.     
  264.     // draw connecting lines between Hit Elements
  265.     glColorC(m_DefaultColor);
  266.     glLineWidth(1.0f);
  267.     glEnable(GL_LINE_STIPPLE);
  268.     glLineStipple(1, 0x5555);
  269.     
  270.     glBegin(GL_LINES);        
  271.         NON_CONST_ITERATE(THitGlyphVector, it, m_vGlyphs)    {
  272.             (*it)->Render(pane, CHitElemGlyph::eConnectionLines);
  273.         }        
  274.     glEnd();
  275.     glDisable(GL_LINE_STIPPLE);
  276. }
  277. void    CHitMatrixGraph::x_RenderPath(CGlPane& pane)
  278. {    
  279.     glEnable(GL_BLEND);
  280.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  281.       
  282.     glEnable(GL_LINE_SMOOTH);
  283.     glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);   
  284.     glLineWidth(6.0f);
  285.     glColor4d(0.8, 0.8, 0.8, 0.5); //###
  286.     
  287.     glBegin(GL_LINES);             
  288.         NON_CONST_ITERATE(TPathCont, it, m_Paths)    { // for each Hit
  289.             TPath& path = *it;
  290.             // for each Hit Elem in the path
  291.             NON_CONST_ITERATE(TPath, itE, path)    {
  292.                 if(! (*itE)->IsSelected()) {
  293.                     int ind = (*itE)->GetColorIndex();
  294.                     const CGlColor* pC = & x_GetColorByIndex(ind);
  295.                     glColor4d(pC->GetRed(), pC->GetGreen(), pC->GetBlue(), 0.25);
  296.                     (*itE)->Render(pane, CHitElemGlyph::eHitElemLines);            
  297.                 }
  298.             }
  299.         }            
  300.     
  301.     // draw connecting lines
  302.     NON_CONST_ITERATE(TPathCont, it, m_Paths)    { // for each Hit
  303.         TPath& path = *it;
  304.         // for each Hit Elem in the path
  305.         TPath::const_iterator it1 = path.begin();
  306.         TPath::const_iterator it2 = ++it1;
  307.         while( it2 != path.end() )  {
  308.             (*it1)->EndVertex();
  309.             (*it2)->StartVertex();            
  310.             it1 = it2;
  311.             it2++;
  312.         }
  313.     }            
  314.     glEnd();
  315. }
  316. void    CHitMatrixGraph::x_RenderSelection(CGlPane& pane)
  317. {
  318.     glEnable(GL_BLEND);
  319.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  320.     
  321.     // draw projection quads
  322.     glColorC(m_ProjBackColor);        
  323.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  324.     glBegin(GL_QUADS);             
  325.          NON_CONST_ITERATE(TElemGlyphSet, it, m_SelGlyphs)    {
  326.            (*it)->Render(pane, CHitElemGlyph::eProjLines);
  327.         }   
  328.     glEnd();
  329.     
  330.     // draw projection lines
  331.     glLineWidth(0.5f);
  332.     glColorC(m_ProjLinesColor);
  333.     
  334.     glBegin(GL_LINES);             
  335.          NON_CONST_ITERATE(TElemGlyphSet, it, m_SelGlyphs)    {
  336.            (*it)->Render(pane, CHitElemGlyph::eProjLines);
  337.         }   
  338.     glEnd();
  339.     // draw highlight
  340.     glEnable(GL_LINE_SMOOTH);
  341.     glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);   
  342.     
  343.     glLineWidth(8.0f);        
  344.     glColorC(m_HighLightColor);        
  345.     glBegin(GL_LINES);             
  346.          NON_CONST_ITERATE(TElemGlyphSet, it, m_SelGlyphs)    {
  347.            (*it)->Render(pane, CHitElemGlyph::eHitElemLines);
  348.         }   
  349.     glEnd();    
  350. }
  351. void    CHitMatrixGraph::x_RenderEventHandler(CGlPane& pane)
  352. {
  353.     if(m_State == eSelRect) {
  354.         _ASSERT(m_pHost);
  355.         CGlAttrGuard AttrGuard(GL_POLYGON_BIT);
  356.         pane.OpenPixels();
  357.         glLineWidth(1.0f);
  358.         glColor3f(0.0f, 0.0f, 0.0f);
  359.         glLineStipple(1, 0x0F0F);
  360.         glEnable(GL_LINE_STIPPLE);
  361.         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  362.         int x1 = m_StartPoint.X(); 
  363.         int y1 = m_pHost->HMGH_GetVPPosByY(m_StartPoint.Y());
  364.         int x2 = m_DragPoint.X();
  365.         int y2 = m_pHost->HMGH_GetVPPosByY(m_DragPoint.Y());
  366.         if(x2 < x1)
  367.             swap(x1, x2);
  368.         if(y2 < y1)
  369.             swap(y1, y2);
  370.         glBegin(GL_LINES);
  371.             glVertex2d(x1, y2);
  372.             glVertex2d(x2, y2);
  373.             glVertex2d(x2, y2);
  374.             glVertex2d(x2, y1);
  375.             glVertex2d(x1, y2);
  376.             glVertex2d(x1, y1);
  377.         
  378.             glVertex2d(x1, y1);
  379.             glVertex2d(x2, y1);
  380.         glEnd();
  381.         glDisable(GL_LINE_STIPPLE);
  382.         pane.Close();
  383.     }
  384. }   
  385. void    CHitMatrixGraph::CreateColorTable(int size)
  386. {
  387.     m_vColors.resize(size);
  388.     static const float base = 0.5f;
  389.     static const float delta = 0.5f;
  390.     float K = 1.0f / (size - 1);
  391.     for( int i = 0;  i < size;  i++ ) {
  392.         float score = i * K;
  393.         float v = (2 * score - 1) * delta;
  394.         float bad = base - v;
  395.         float good = base + v;
  396.         m_vColors[i] =  CGlColor(bad, good, 0, kHitAlpha);        
  397.     }
  398. }
  399. void    CHitMatrixGraph::AssignColorsByScore(CConstRef<CObject_id> score_id)
  400. {
  401.     double min_v = 0, max_v = 0;
  402.     bool b_init = false;
  403.     size_t size = m_vGlyphs.size();
  404.     vector<double>  values(size);
  405.     for( size_t i = 0; i < size;  i++ )    {
  406.         double v = m_vGlyphs[i]->GetHit().GetScoreValue(score_id.GetObject());
  407.         values[i] = v;
  408.         if(b_init)  {
  409.             min_v = min(min_v, v);
  410.             max_v = max(max_v, v);
  411.         } else {
  412.             min_v = max_v = v;
  413.             b_init = true;
  414.         }
  415.     }
  416.     size_t color_n = m_vColors.size();
  417.     double range = max_v - min_v;
  418.     for( size_t i = 0; i < size;  i++ )    {
  419.         double norm = (values[i] - min_v) / range;
  420.         size_t ind = (size_t) floor(norm * color_n);
  421.         ind = (ind == color_n) ? --ind : ind;
  422.         m_vGlyphs[i]->SetColorIndex(ind);
  423.     }
  424. }
  425. void    CHitMatrixGraph::SetHost(IHitMatrixGraphHost* pHost)
  426. {
  427.     m_pHost = pHost;
  428. }
  429. int     CHitMatrixGraph::handle(CGUIEvent& event, CGlPane& pane)
  430. {
  431.     m_pPane = &pane;
  432.     int res = 0;
  433.     switch(event.GetFLTKEvent())   {
  434.     case FL_PUSH: res =  x_OnMousePush(event); break;
  435.     case FL_DRAG: res =  x_OnMouseDrag(event); break;
  436.     case FL_RELEASE: res =  x_OnMouseRelease(event); break;
  437.     case FL_MOVE: res =  x_OnMouseMove(); break;
  438.     case FL_KEYDOWN: res =  x_OnKeyDown(); break;
  439.     case FL_KEYUP: res =  x_OnKeyUp(); break;
  440.     }
  441.     m_pPane = NULL;
  442.     return res;
  443. }
  444. ////////////////////////////////////////////////////////////////////////////////
  445. /// event handlers
  446. int CHitMatrixGraph::x_OnMousePush(CGUIEvent& event)
  447. {    
  448.     CGUIEvent::EGUIState state = event.GetGUIState();
  449.     if((state == CGUIEvent::eSelectState  ||  state == CGUIEvent::eSelectIncState)
  450.         && event.GetGUISignal() == CGUIEvent::eSelectSignal)    {
  451.         if(Fl::event_clicks() == 0) {            
  452.             m_State = eSelPoint;
  453.             m_StartPoint.m_X = Fl::event_x();
  454.             m_StartPoint.m_Y = Fl::event_y();
  455.             m_DragPoint = m_StartPoint;
  456.             bool b_inc = event.GetGUIState() == CGUIEvent::eSelectIncState;
  457.             bool b_selected = x_SelectByPoint(b_inc);  
  458.             m_State = b_selected ? eSelPoint : eSelRect;
  459.             
  460.             m_pHost->HMGH_Redraw();
  461.             x_OnSelectCursor();
  462.         }                
  463.         return 1;
  464.     }
  465.     return 0;
  466. }
  467. int CHitMatrixGraph::x_OnMouseDrag(CGUIEvent& event)
  468. {
  469.     CGUIEvent::EGUIState state = event.GetGUIState();
  470.     if(m_State == eSelRect  &&  (state == CGUIEvent::eSelectState
  471.         || state == CGUIEvent::eSelectIncState) )   {
  472.         
  473.         if(Fl::event_x() != m_DragPoint.X()  ||  Fl::event_y() != m_DragPoint.Y())  {
  474.             m_State = eSelRect;
  475.             m_DragPoint.m_X = Fl::event_x();
  476.             m_DragPoint.m_Y = Fl::event_y();
  477.             m_pHost->HMGH_Redraw();
  478.             x_OnSelectCursor();        
  479.         }
  480.     } 
  481.     return 1; // always handle drags
  482. }
  483. int CHitMatrixGraph::x_OnMouseRelease(CGUIEvent& event)
  484. {   
  485.     CGUIEvent::EGUIState state = event.GetGUIState();
  486.     if(m_State == eSelPoint)    {
  487.         return 1;
  488.     }
  489.     if(m_State == eSelRect  &&  (state == CGUIEvent::eSelectState
  490.         || state == CGUIEvent::eSelectIncState) 
  491.         &&  event.GetGUISignal() == CGUIEvent::eRelease)   {
  492.         
  493.         bool b_inc = event.GetGUIState() == CGUIEvent::eSelectIncState;       
  494.         x_SelectByRect(b_inc);
  495.         
  496.         m_State = eIdle;
  497.         m_pHost->HMGH_Redraw();
  498.         x_OnSelectCursor();        
  499.         return 1;
  500.     }
  501.     return 0;
  502. }
  503. int CHitMatrixGraph::x_OnMouseMove(void)
  504. {
  505.     return (m_State == eIdle) ? 0 : 1;
  506. }
  507. int CHitMatrixGraph::x_OnKeyDown(void)
  508. {
  509.     return (m_State == eIdle) ? 0 : 1;
  510. }
  511. int CHitMatrixGraph::x_OnKeyUp(void)
  512. {
  513.     return (m_State == eIdle) ? 0 : 1;
  514. }
  515. void    CHitMatrixGraph::x_OnSelectCursor(void)
  516. {
  517.     switch(m_State)    {
  518.     case eIdle:  m_Cursor = FL_CURSOR_DEFAULT; break;
  519.     case eSelPoint: m_Cursor = FL_CURSOR_DEFAULT; break;
  520.     case eSelRect: m_Cursor = FL_CURSOR_CROSS; break;
  521.     default: break;
  522.     }   
  523.     fl_cursor(m_Cursor, FL_BLACK, FL_WHITE);
  524. }
  525. static int kHitTestPrecision = 5;
  526. bool    CHitMatrixGraph::x_SelectByPoint(bool b_inc)
  527. {
  528.     double min_d = -1;
  529.     CHitElemGlyph*  p_hit_elem = NULL;
  530.     TVPPoint pt(m_StartPoint.X(), m_pHost->HMGH_GetVPPosByY(m_StartPoint.Y()));
  531.     NON_CONST_ITERATE(THitGlyphVector, it, m_vGlyphs)    { // for each Hit
  532.         CHitGlyph::TElemGlyphCont& elems = (*it)->GetElems();
  533.         // for each Hit Element
  534.         NON_CONST_ITERATE(CHitGlyph::TElemGlyphCont, itE, elems)    {    
  535.             double d = itE->GetDistPixels(*m_pPane, pt);
  536.             if(! p_hit_elem  ||  d < min_d )  {
  537.                 min_d = d;
  538.                 p_hit_elem = &(*itE);
  539.             }
  540.         }
  541.     }
  542.     if(! b_inc)  { // operation not incremental - clear selection
  543.         NON_CONST_ITERATE(TElemGlyphSet, it, m_SelGlyphs)   {
  544.             (*it)->SetSelected(false);
  545.         }
  546.         m_SelGlyphs.clear();
  547.     }    
  548.     if(p_hit_elem  &&  min_d <= kHitTestPrecision)  { 
  549.         if(b_inc  &&  p_hit_elem->IsSelected()) {
  550.             p_hit_elem->SetSelected(false);
  551.             m_SelGlyphs.erase(p_hit_elem);
  552.         } else {
  553.             p_hit_elem->SetSelected(true);
  554.             m_SelGlyphs.insert(p_hit_elem);
  555.         }
  556.         return true;
  557.     }
  558.     return false;
  559. }
  560. void    CHitMatrixGraph::x_SelectByRect(bool b_inc)
  561. {
  562.     if(!b_inc)  { // operation not incremental - reset selection
  563.         NON_CONST_ITERATE(TElemGlyphSet, it, m_SelGlyphs)   {
  564.             (*it)->SetSelected(false);
  565.         }
  566.         m_SelGlyphs.clear();
  567.     }
  568.     int x1 = m_StartPoint.X();
  569.     int y1 = m_pHost->HMGH_GetVPPosByY(m_StartPoint.Y());
  570.     int x2 = m_DragPoint.X();
  571.     int y2 = m_pHost->HMGH_GetVPPosByY(m_DragPoint.Y());
  572.     TVPRect rc( min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));
  573.     NON_CONST_ITERATE(THitGlyphVector, it, m_vGlyphs)    { // for each Hit
  574.         CHitGlyph::TElemGlyphCont& elems = (*it)->GetElems();
  575.         // for each Hit Element
  576.         NON_CONST_ITERATE(CHitGlyph::TElemGlyphCont, itE, elems)    {    
  577.             bool b_inside = itE->InRect(*m_pPane, rc);
  578.             if(b_inside)    {
  579.                 itE->SetSelected(true);
  580.                 m_SelGlyphs.insert(&(*itE));
  581.             }
  582.         }
  583.     }
  584. }
  585. END_NCBI_SCOPE
  586. /*
  587.  * ===========================================================================
  588.  * $Log: hit_matrix_graph.cpp,v $
  589.  * Revision 1000.3  2004/06/01 21:10:56  gouriano
  590.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.11
  591.  *
  592.  * Revision 1.11  2004/05/21 22:27:54  gorelenk
  593.  * Added PCH ncbi_pch.hpp
  594.  *
  595.  * Revision 1.10  2004/03/08 15:54:20  yazhuk
  596.  * Fixed CGlAttrGuard usage
  597.  *
  598.  * Revision 1.9  2004/02/17 15:21:52  yazhuk
  599.  * Refactoring - removed CGlEnabler CGlParam
  600.  *
  601.  * Revision 1.8  2004/01/08 19:48:05  yazhuk
  602.  * Minor clean-up
  603.  *
  604.  * Revision 1.7  2003/12/05 17:45:13  yazhuk
  605.  * Added function for retrieving selection, modified AssignColorByScore(); cleaned-up
  606.  *
  607.  * Revision 1.6  2003/12/01 22:36:56  yazhuk
  608.  * Fixed GCC compilation problems
  609.  *
  610.  * Revision 1.5  2003/12/01 17:08:28  yazhuk
  611.  * Redesigned classes in accordance with the new data model.
  612.  *
  613.  * Revision 1.4  2003/11/18 18:06:14  ucko
  614.  * Fixed gcc ERRORS - should #include <math.h> and call fabs() rather than
  615.  * abs() for doubles.
  616.  *
  617.  * Revision 1.3  2003/11/18 17:57:23  yazhuk
  618.  * Fixed GCC warnings
  619.  *
  620.  * Revision 1.2  2003/11/18 00:05:59  yazhuk
  621.  * GCC compilation fixes
  622.  *
  623.  * Revision 1.1  2003/11/17 20:41:19  yazhuk
  624.  * Initial revision
  625.  *
  626.  * ===========================================================================
  627.  */