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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: cross_aln_pane.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 21:06:28  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: cross_aln_pane.cpp,v 1000.2 2004/06/01 21:06:28 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 "cross_aln_pane.hpp"
  39. #include <gui/utils/fltk_utils.hpp>
  40. #include <gui/widgets/seq_graphic/seqgraphic_conf.hpp>
  41. #include <objmgr/util/feature.hpp>
  42. #include <util/regexp.hpp>
  43. #include <algorithm>
  44. #include <math.h>
  45. #include <FL/glut.H>
  46. #include <FL/fl_draw.H>
  47. BEGIN_NCBI_SCOPE
  48. const TModelUnit kMouseZoomFactor = 25.0;   // per pixel of mouse movement
  49. CCrossAlnPane::CCrossAlnPane(int x, int y, int w, int h, const char* label)
  50.     : CGlCanvas2d(x, y, w, h, label)
  51.     m_ConfigSettings.Reset( new CSeqGraphicConfig(NULL) ); // init with default settings
  52.    
  53.     m_Renderer.Reset(new CCrossAlnRenderer());
  54.     m_Renderer->SetConfig(m_ConfigSettings);
  55.     
  56.     m_Event.StandardConfig();
  57.     m_MouseZoomHandler.SetHost(static_cast<IMouseZoomHandlerHost*>(this));
  58.     m_Tooltip.EnableActiveMode(static_cast<ITooltipClient*>(this));
  59.     m_Tooltip.SetMode(CTooltip::eHideOnMove);
  60. }
  61. CCrossAlnPane::~CCrossAlnPane()
  62. {
  63. }
  64. void CCrossAlnPane::SetDataSource(CCrossAlnDataSource* ds)
  65. {
  66.     TVPRect rc(5, 5, w() - 5, h() - 5);
  67.     m_Renderer->SetDataSource(rc, ds);
  68.     m_DS.Reset(ds);
  69.     Update();
  70.     
  71.     //invalidate();
  72.     //redraw();
  73. }
  74. void CCrossAlnPane::SelectObject(const CObject* obj)
  75. {
  76.     if (!obj) {
  77.         return;
  78.     }
  79.     m_Renderer->SelectObject(obj);
  80.     redraw();
  81. }
  82. void CCrossAlnPane::ClearSelection()
  83. {
  84.     m_Renderer->ClearObjectSelection();
  85. }
  86. void CCrossAlnPane::Update()
  87. {
  88.     m_Renderer->Update();
  89.     
  90.     invalidate();
  91.     redraw();
  92. }
  93. // retrieve the selections from our renderer
  94. const TConstObjects& CCrossAlnPane::GetSelectedObjects(void) const
  95. {
  96.     return m_Renderer->GetSelectedObjects();
  97. }
  98. void CCrossAlnPane::x_AdjustScrollBars(void)
  99. {
  100.     Fl_Scrollbar* scrollX1 = (Fl_Scrollbar*)(parent()->parent()->child(0));
  101.     Fl_Scrollbar* scrollY1 = (Fl_Scrollbar*)(parent()->parent()->child(1));
  102.     Fl_Scrollbar* scrollX2 = (Fl_Scrollbar*)(parent()->parent()->child(2));
  103.     Fl_Scrollbar* scrollY2 = (Fl_Scrollbar*)(parent()->parent()->child(3));
  104.     scrollX1->linesize(1);
  105.     scrollY1->linesize(1);
  106.     scrollX2->linesize(1);
  107.     scrollY2->linesize(1);
  108.     
  109.     const TModelRect& rcV1 = m_Renderer->GetFeatGlPane1().GetVisibleRect();
  110.     const TModelRect& rcM1 = m_Renderer->GetFeatGlPane1().GetModelLimitsRect();
  111.     const TModelRect& rcV2 = m_Renderer->GetFeatGlPane2().GetVisibleRect();
  112.     const TModelRect& rcM2 = m_Renderer->GetFeatGlPane2().GetModelLimitsRect();
  113.     
  114.     scrollX1->value(int(rcV1.Left()), int(rcV1.Width()), 0, int(rcM1.Width()-1));
  115.     scrollX2->value(int(rcV2.Left()), int(rcV2.Width()), 0, int(rcM2.Width()-1));
  116.                    
  117.     if (m_Renderer->GetFeatGlPane1().NeedsScrollX()) {
  118.         scrollX1->show();
  119.     } else {
  120.         scrollX1->hide();
  121.     }    
  122.     
  123.     if (m_Renderer->GetFeatGlPane2().NeedsScrollX()) {
  124.         scrollX2->show();
  125.     } else {
  126.         scrollX2->hide();
  127.     }    
  128.     
  129.     scrollX1->linesize( int(m_Renderer->GetScrollLineSize1()) );
  130.     scrollX1->linesize( int(m_Renderer->GetScrollLineSize2()) );
  131.     scrollY1->value(int(rcV1.Bottom()), abs(int(rcV1.Height())), 
  132.                     0, abs(int(rcM1.Height())) );
  133.     scrollY2->value(int(rcV2.Top()), abs(int(rcV2.Height())), 
  134.                     0, abs(int(rcM2.Height())) );
  135. }
  136. void CCrossAlnPane::draw()
  137. {
  138.     if (!valid()) {
  139.         TVPRect rc(5, 5, w() - 5, h() - 5);
  140.         m_Renderer->resize(rc);
  141.     }
  142.     
  143.     glClearColor(1, 1, 1, 0);
  144.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  145.     if ( !m_DS ) {
  146.         return;
  147.     }
  148.     
  149.     m_Renderer->draw();
  150.     // ZoomHandler indicator
  151.     if (m_HitPane) {
  152.         glEnable(GL_BLEND);
  153.         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  154.         m_MouseZoomHandler.Render(*m_HitPane);
  155.         glDisable(GL_BLEND);
  156.     }
  157.     
  158.     x_AdjustScrollBars();
  159.     
  160.     return;
  161. }
  162. int CCrossAlnPane::handle(int event)
  163. {
  164.     // Handle focus events before everything else
  165.     if (event == FL_FOCUS  || event == FL_UNFOCUS) { 
  166.         redraw(); 
  167.         return 1; 
  168.     }
  169.     // Always acquire focus, otherwise keyboard events do not get into the panel
  170.     if(event == FL_PUSH  &&  Fl::focus() != static_cast<Fl_Widget*>(this)) {
  171.         take_focus();
  172.     }
  173.     
  174.     // Process event and feed it to ZoomHandler
  175.     m_Event.OnFLTKEvent(event);
  176.     
  177.     if (m_HitPane) {
  178.         m_MouseZoomHandler.handle(m_Event, *m_HitPane);
  179.     }
  180.     // pass events to the tooltip object
  181.     m_Tooltip.Handle(event);
  182.     CFltkEvent::EEvent ev = CFltkEvent::GetProcessedEvent();
  183.     
  184.     int ev_x = Fl::event_x();
  185.     int ev_y = Fl::event_y();
  186.     const CLayoutObject* obj = NULL;
  187.     //
  188.     // "typed" FLTK event handling
  189.     //
  190.     switch (ev) {
  191.     case CFltkEvent::eSelectState:
  192.     case CFltkEvent::eMultiSelectState:
  193.         switch (event) {
  194.         case FL_PUSH:
  195.             m_HitPane = m_Renderer->PaneHitTest(ev_x, h()-ev_y);
  196.             m_HitPanel = m_Renderer->PanelHitTest(ev_x, h()-ev_y);
  197.             
  198.             obj = m_Renderer->HitTest(ev_x, h()-ev_y);
  199.             
  200.             if (ev == CFltkEvent::eSelectState)  {
  201.                 m_Renderer->ClearObjectSelection();
  202.             }
  203.             
  204.             if (obj) {
  205.                 const CObject* sel_obj = obj->GetObject( 
  206.                       TSeqPos(m_HitPane->UnProjectX(ev_x)) );
  207.                 SelectObject(sel_obj);
  208.             }
  209.             
  210.             // double click zooms on the feature/alignment/etc
  211.             if (Fl::event_clicks()) {
  212.                 m_Renderer->ZoomOnObject(obj);
  213.             }
  214.             
  215.             // ping the callback on selection
  216.             // sequence dragging pings the callback on release only
  217.             parent()->parent()->do_callback();
  218.             
  219.             redraw();
  220.             return 1;
  221.         case FL_DRAG:
  222.             return 1;
  223.         case FL_RELEASE:
  224.             m_HitPane = NULL;
  225.             return 1;
  226.         default:
  227.             break;
  228.         }
  229.         break;
  230.     default:
  231.         break;
  232.     }
  233.     return CGlCanvas2d::handle(event);
  234. }
  235. // IMouseZoomHandlerHost implementation
  236. TModelUnit CCrossAlnPane::MZHH_GetScale(EScaleType type)
  237. {
  238.     switch(type) {
  239.     case eCurrent: return m_HitPane->GetScaleX();
  240.     case eMin:     return m_HitPane->GetMinScaleX();
  241.     case eMax:     return m_HitPane->GetZoomAllScaleX();
  242.     default: _ASSERT(false); return -1;
  243.     }
  244. }
  245. void CCrossAlnPane::MZHH_SetScale(TModelUnit scale, const TModelPoint& point)
  246. {
  247.     if (m_HitPanel == CCrossAlnRenderer::eFeatures1) {
  248.         m_Renderer->SetScaleRef1(scale, m_HitPane->GetScaleY(), point);
  249.     } else if (m_HitPanel == CCrossAlnRenderer::eFeatures2) {
  250.         m_Renderer->SetScaleRef2(scale, m_HitPane->GetScaleY(), point);
  251.     } else if (m_HitPanel == CCrossAlnRenderer::eCross) {
  252.         m_Renderer->SetScaleRefC(scale, m_HitPane->GetScaleY(), point);
  253.     }
  254.     redraw();
  255. }
  256. void CCrossAlnPane::MZHH_ZoomRect(const TModelRect& rc)
  257. {
  258.     ZoomOnRange( TSeqRange(TSeqPos(rc.Left()), TSeqPos(rc.Right())) );
  259. }
  260. void CCrossAlnPane::MZHH_Scroll(TModelUnit d_x, TModelUnit d_y)
  261. {
  262.     const TModelRect& rc1 = m_Renderer->GetFeatGlPane1().GetVisibleRect();
  263.     const TModelRect& rc2 = m_Renderer->GetFeatGlPane2().GetVisibleRect();
  264.     
  265.     if (m_HitPanel == CCrossAlnRenderer::eFeatures1) {
  266.         Scroll(rc1.Left() + d_x, 0, rc2.Left(), 0);
  267.     } else {
  268.         Scroll(rc1.Left(), 0, rc2.Left() + d_x, 0);
  269.     }
  270. }
  271. TVPUnit CCrossAlnPane::MZHH_GetVPPosByY(int y) const
  272. {
  273.     return h() - 1  - y;
  274. }
  275. void CCrossAlnPane::MZHH_Redraw(void)
  276. {
  277.     redraw();
  278. }
  279. // IMouseZoomHandlerHost end
  280. ///////////////////////////////////////////////////////////////////////////////
  281. /// ITooltip Implementation
  282. bool CCrossAlnPane::TC_NeedTooltip(int x, int y)
  283. {
  284.     m_Renderer->GetTooltip(x, h() - y, &m_TooltipText);
  285.     return m_TooltipText.length() > 0;
  286. }
  287. string CCrossAlnPane::TC_GetTooltip(int& x, int& y, int& w, int& h)
  288. {
  289.     return m_TooltipText;
  290. }
  291. // ITooltip end
  292. // --- Scrolling --------------------------------------------------
  293. void CCrossAlnPane::Scroll(TModelUnit x1, TModelUnit y1, 
  294.                            TModelUnit x2, TModelUnit y2)
  295. {
  296.     // "lock" both scrollbars if Shift key is pressed. That will scroll all panels
  297.     // together (withing each panel limits)
  298.     if (Fl::event_shift()) {
  299.         const TModelRect& rc1 = m_Renderer->GetFeatGlPane1().GetVisibleRect();
  300.         const TModelRect& rc2 = m_Renderer->GetFeatGlPane2().GetVisibleRect();
  301.     
  302.         // Find the scroll "delta"
  303.         int dX1 = int(x1 - rc1.Left());
  304.         int dX2 = int(x2 - rc2.Left());
  305.         
  306.         if (dX1 != 0) x2 = x2 + dX1;
  307.         if (dX2 != 0) x1 = x1 + dX2;
  308.     }
  309.     m_Renderer->Scroll(x1, y1, x2, y2);
  310.     
  311.     redraw();
  312. }
  313. void CCrossAlnPane::ZoomOnRange(const TSeqRange& range)
  314. {
  315.     m_Renderer->ZoomOnRange(range);
  316. }
  317. void CCrossAlnPane::ZoomOnAlignment()
  318. {
  319.     m_Renderer->ZoomOnAlignment();
  320.     
  321.     redraw();
  322. }
  323. void CCrossAlnPane::FitToWindow(void)
  324. {
  325.     m_Renderer->FitToWindow();
  326. }
  327. void CCrossAlnPane::ZoomToSequence(void)
  328. {
  329.     m_Renderer->ZoomToSequence();
  330. }
  331. TSeqRange CCrossAlnPane::GetVisibleRange()
  332. {
  333.     const TModelRect& rc = m_Renderer->GetFeatGlPane1().GetVisibleRect();
  334.     return TSeqRange( TSeqPos(rc.Left()), TSeqPos(rc.Right()) );
  335. }
  336. void CCrossAlnPane::SetConfig(CRef<CSeqGraphicConfig> config)
  337. {
  338.     m_ConfigSettings = config;
  339.     m_Renderer->SetConfig(m_ConfigSettings);
  340. }
  341.     
  342.     
  343. END_NCBI_SCOPE
  344. /*
  345.  * ===========================================================================
  346.  * $Log: cross_aln_pane.cpp,v $
  347.  * Revision 1000.2  2004/06/01 21:06:28  gouriano
  348.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8
  349.  *
  350.  * Revision 1.8  2004/05/21 22:27:52  gorelenk
  351.  * Added PCH ncbi_pch.hpp
  352.  *
  353.  * Revision 1.7  2004/04/16 14:49:02  dicuccio
  354.  * Use TConstObjects for handling object selections
  355.  *
  356.  * Revision 1.6  2004/04/16 12:28:26  lebedev
  357.  * Use correct CGlPane to UnProject x coordinate for selection.
  358.  *
  359.  * Revision 1.5  2004/04/16 12:07:28  lebedev
  360.  * Use new GetObject(TSeqPos) method is CLayoutObject
  361.  *
  362.  * Revision 1.4  2004/03/11 17:50:41  dicuccio
  363.  * Updated typedefs: dropped TDimension, TPosition, TIndex, TColor; use TSeqRange
  364.  * instead of TRange
  365.  *
  366.  * Revision 1.3  2004/01/27 16:20:40  lebedev
  367.  * Changed stored selection from CLayoutObject to CObject
  368.  *
  369.  * Revision 1.2  2004/01/16 13:40:38  lebedev
  370.  * Tooltips added
  371.  *
  372.  * Revision 1.1  2003/12/22 13:12:33  lebedev
  373.  * Initial revision
  374.  *
  375.  * ===========================================================================
  376.  */