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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: seqgraphic_pane.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 21:12:53  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.31
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: seqgraphic_pane.cpp,v 1000.2 2004/06/01 21:12:53 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 "seqgraphic_pane.hpp"
  39. #include <gui/utils/fltk_utils.hpp>
  40. #include <gui/objutils/obj_clipboard.hpp>
  41. #include <gui/widgets/seq_graphic/seqgraphic_conf.hpp>
  42. #include <gui/config/feat_config_list.hpp>
  43. #include <objmgr/util/feature.hpp>
  44. #include <util/regexp.hpp>
  45. #include <algorithm>
  46. #include <math.h>
  47. #include <FL/glut.H>
  48. #include <FL/fl_draw.H>
  49. BEGIN_NCBI_SCOPE
  50. const TModelUnit kMouseZoomFactor = 25.0;   // per pixel of mouse movement
  51. CSeqGraphicPane::CSeqGraphicPane(int x, int y, int w, int h)
  52.     : CGlPaneWidgetChild(x, y, w, h, "")
  53. {
  54.     m_VisibleRangeChanged = false;
  55.     m_Renderer.Reset(new CSeqGraphicRenderer());
  56.     
  57.     m_Event.StandardConfig();
  58.     
  59.     // Register additional widget-specific states
  60.     // ZoomIn, ZoomOut and Lense Zoom:
  61.     m_Event.RegisterState(CGUIEvent::eInsZoomStateIn,                  0, 'i');
  62.     m_Event.RegisterState(CGUIEvent::eInsZoomStateOut, CGUIEvent::fShift, 'i');
  63.     m_Event.RegisterState(CGUIEvent::eLensZoomState,                   0, 'l');
  64.     
  65.     /**
  66.     m_Event.RegisterState(eLensZoomState, 0, 'l');
  67.     m_Event.RegisterState(eZoomInState,      0, '+');
  68.     m_Event.RegisterState(eZoomOutState,     0, '-');
  69.     m_Event.RegisterState(eZoomInFullState,  0, '*');
  70.     m_Event.RegisterState(eZoomOutFullState, 0, '=');
  71.     **/
  72.     m_TimerActive = false;
  73.     //m_MouseScrollHandler.SetHost(static_cast<IMouseScrollHandlerHost*>(this));
  74.     //x_RegisterHandler(dynamic_cast<IEventHandler*>(&m_MouseScrollHandler), fScrollArea, &m_Renderer->GetFixedGlPane());
  75.     m_MouseZoomHandler.SetHost(static_cast<IMouseZoomHandlerHost*>(this));
  76.     x_RegisterHandler(dynamic_cast<IEventHandler*>(&m_MouseZoomHandler), fFeaturesArea, &m_Renderer->GetFeatGlPane());
  77.     
  78.     m_SelHandler.SetHost(static_cast<ISelHandlerHost*>(this));
  79.     x_RegisterHandler(dynamic_cast<IEventHandler*>(&m_SelHandler), fSeqRulerArea, &m_Renderer->GetRulerGlPane());
  80.     
  81.     m_Tooltip.EnableActiveMode(static_cast<ITooltipClient*>(this));
  82.     m_Tooltip.SetMode(CTooltip::eHideOnMove);
  83. }
  84. CSeqGraphicPane::~CSeqGraphicPane()
  85. {
  86. }
  87. void CSeqGraphicPane::SetDataSource(CSeqGraphicDataSource* ds)
  88. {
  89.     TVPRect rc(0, 0, w() - 0, h() - 0);
  90.     m_Renderer->SetDataSource(rc, ds);
  91.     m_DS.Reset(ds);
  92.     
  93.     m_SelHandler.ResetSelection(false);
  94.     
  95.     invalidate();
  96.     redraw();
  97. }
  98. void CSeqGraphicPane::SetWidget(CSeqGraphicWidget* widget)
  99. {
  100.     m_ParentWidget = widget;
  101. }
  102. // Set/Clear selection
  103. void CSeqGraphicPane::SelectObject(const CObject* obj)
  104. {
  105.     if (!obj) {
  106.         return;
  107.     }
  108.     
  109.     m_LastSelObj.Reset(obj);
  110.     
  111.     m_Renderer->SelectObject(obj);
  112.     redraw();
  113. }
  114. void CSeqGraphicPane::SelectSeqLoc(const CSeq_loc* loc)
  115. {
  116.     TRangeColl r = TRangeColl( loc->GetTotalRange() );
  117.     m_SelHandler.SetSelection(r, false);
  118.     redraw();
  119. }
  120. void CSeqGraphicPane::ClearSelection()
  121. {
  122.     m_SelHandler.ResetSelection(false);
  123.     m_Renderer->ClearObjectSelection();
  124.     
  125.     redraw();
  126. }
  127. // retrieve the selections from our renderer
  128. const TConstObjects& CSeqGraphicPane::GetSelectedObjects(void) const
  129. {
  130.     return m_Renderer->GetSelectedObjects();
  131. }
  132. const CSeqGraphicPane::TRangeColl&
  133. CSeqGraphicPane::GetSelectedSeqRanges(void) const
  134. {
  135.     return m_SelHandler.GetSelection();
  136. }
  137. const CSeqGraphicDataSource* CSeqGraphicPane::GetDataSource(void) const
  138. {
  139.     return m_DS.GetPointer();
  140. }
  141. void CSeqGraphicPane::SetZoomX(float value)
  142. {
  143.     m_Renderer->SetZoomX(value);
  144.     // indicate a visible range change
  145.     m_VisibleRangeChanged = true;
  146.     invalidate();
  147.     redraw();
  148. }
  149. int CSeqGraphicPane::SearchFeature(string pattern,
  150.         string feature, bool is_local)
  151. {
  152.     m_SearchResults.clear();
  153.     m_SearchIndex = 0;
  154.         
  155.     int (*pf)(int) = tolower;  // explicit cast to resolve the ambiguity
  156.     
  157.     const TModelRect& rc = is_local ? 
  158.                            m_Renderer->GetFeatGlPane().GetVisibleRect() : 
  159.                            m_Renderer->GetFeatGlPane().GetModelLimitsRect();
  160.                                       
  161.     TSeqRange range = TSeqRange(TSeqPos(rc.Left()), TSeqPos(rc.Right()));
  162.     
  163.     std::transform(pattern.begin(), pattern.end(), 
  164.                    pattern.begin(), pf);
  165.     CRegexp exp_pattern(pattern);
  166.     
  167.     int type, sub_type;
  168.     GetFeatConfigList()->GetTypeSubType(feature, type, sub_type);
  169.     SAnnotSelector selector =
  170.         CSeqUtils::GetAnnotSelector
  171.         (static_cast<CSeqFeatData::ESubtype>(sub_type));
  172.     
  173.     CLayoutFeat::TFeatList feats;
  174.     CSeqUtils::GetFeatures(m_DS->GetBioseqHandle(), range, selector, feats);
  175.     NON_CONST_ITERATE (CLayoutFeat::TFeatList, iter, feats) {
  176.         CLayoutFeat& feat = **iter;
  177.         
  178.         string label;
  179.         feature::GetLabel(feat.GetFeature(), &label, 
  180.                           feature::eContent,
  181.                           &m_DS->GetBioseqHandle().GetScope());
  182.                           
  183.         std::transform(label.begin(), label.end(), label.begin(), pf);
  184.         
  185.         if (exp_pattern.GetMatch(label.c_str()).length() > 0) {
  186.             m_SearchResults.push_back(*iter);
  187.         }
  188.     }
  189.     if (m_SearchResults.size() > 0) 
  190.         m_Renderer->ZoomOnObject(m_SearchResults[m_SearchIndex]);  // actual zoom
  191.     
  192.     
  193.     invalidate();
  194.     redraw();
  195.     
  196.     return m_SearchResults.size();
  197. }
  198. int CSeqGraphicPane::SearchFeatureNext()
  199. {
  200.    if (m_SearchIndex < m_SearchResults.size() - 1) {
  201.         ++m_SearchIndex;
  202.         m_Renderer->ZoomOnObject(m_SearchResults[m_SearchIndex]);
  203.         
  204.         invalidate();
  205.         redraw();
  206.     }
  207.     return m_SearchIndex;
  208. }
  209. int CSeqGraphicPane::SearchFeaturePrev()
  210. {
  211.     if (m_SearchIndex > 0) {
  212.         m_SearchIndex--;
  213.         m_Renderer->ZoomOnObject(m_SearchResults[m_SearchIndex]);
  214.         
  215.         invalidate();
  216.         redraw();
  217.     }
  218.     return m_SearchIndex;
  219. }
  220. void CSeqGraphicPane::x_AdjustScrollBars(void)
  221. {
  222.     Fl_Scrollbar* scrollX = (Fl_Scrollbar*)(parent()->parent()->child(0));
  223.     Fl_Scrollbar* scrollY = (Fl_Scrollbar*)(parent()->parent()->child(1));
  224.     scrollX->linesize(1);
  225.     scrollY->linesize(1);
  226.     
  227.     const TModelRect& rcV = m_Renderer->GetFeatGlPane().GetVisibleRect();
  228.     const TModelRect& rcM = m_Renderer->GetFeatGlPane().GetModelLimitsRect();
  229.     
  230.     scrollX->value(int(rcV.Left()), int(rcV.Width()), 0, int(rcM.Width()-1));
  231.                    
  232.     if (m_Renderer->GetFeatGlPane().NeedsScrollX()) {
  233.         scrollX->show();
  234.     } else {
  235.         scrollX->hide();
  236.     }    
  237.     scrollX->linesize( int(m_Renderer->GetScrollLineSize()) );
  238.     scrollY->value(int(rcV.Top()), abs(int(rcV.Height())), 
  239.                    0, abs(int(rcM.Height())) );
  240.     /*if (m_Renderer->NeedsScrollY()) {
  241.         scrollY->show();
  242.     } else {
  243.         scrollY->hide();
  244.     }*/
  245. }
  246. void CSeqGraphicPane::x_AdjustZoomSlider(void)
  247. {
  248.     Fl_Value_Slider* m_SlideZoomX =
  249.         (Fl_Value_Slider*)(parent()->parent()->child(2));
  250.         
  251.     m_SlideZoomX->range(0, 1);
  252.     m_SlideZoomX->value(m_Renderer->GetZoomX());
  253.     m_SlideZoomX->step(0.001);
  254. }
  255. void CSeqGraphicPane::x_Render()
  256. {
  257.     if (!valid()) {
  258.         TVPRect rc(0, 0, w() - 0, h() - 0);
  259.         m_Renderer->Resize(rc);
  260.     }
  261.     
  262.     glClearColor(1, 1, 1, 0);
  263.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  264.     if ( !m_DS ) {
  265.         return;
  266.     }
  267.     
  268.     m_Renderer->Render();
  269.     
  270.     // ZoomHandler indicator and Linear selection
  271.     glEnable(GL_BLEND);
  272.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  273.     m_MouseZoomHandler.Render(m_Renderer->GetFeatGlPane());
  274.     
  275.     //m_MouseScrollHandler.Render(m_Renderer->GetFixedGlPane());
  276.     // draw linear selection
  277.     CGlColor m_SelGray      (0.5f, 0.5f, 0.5f, 0.20f);
  278.     CGlColor m_SelBlue      (0.0f, 0.0f, 0.5f, 0.50f);
  279.     CGlColor m_SelBlueBorder(0.0f, 0.0f, 0.6f, 0.55f);
  280.             
  281.     
  282.     // draw linear selection
  283.     m_SelHandler.SetColor(CLinearSelHandler::eSelection, m_SelBlue);
  284.     m_SelHandler.SetColor(CLinearSelHandler::ePasssiveSelection, m_SelBlueBorder);
  285.     m_SelHandler.Render(m_Renderer->GetRulerGlPane());
  286.     
  287.     m_SelHandler.SetColor(CLinearSelHandler::ePasssiveSelection, m_SelGray);
  288.     
  289.     // Linear selection handler does not honor EnableOffset flags yet
  290.     // disable offsets before drawing and reenable them after
  291.     m_Renderer->GetFeatGlPane().EnableOffset(false);
  292.     m_SelHandler.Render(m_Renderer->GetFeatGlPane(), CLinearSelHandler::ePassiveState);
  293.     m_Renderer->GetFeatGlPane().EnableOffset(true);
  294.     
  295.     glDisable(GL_BLEND);
  296.     
  297.     x_AdjustScrollBars();
  298.     x_AdjustZoomSlider();
  299. }
  300. int CSeqGraphicPane::handle(int event)
  301. {
  302.     int ev_x = Fl::event_x();
  303.     int ev_y = Fl::event_y();
  304.     CGUIEvent::EGUIState  state  = m_Event.GetGUIState();
  305.     CGUIEvent::EGUISignal signal = m_Event.GetGUISignal();
  306.     
  307.     switch (state) {
  308.     case CGUIEvent::eCopyState:
  309.         x_Handle_ClipboardCopy();
  310.         break;
  311.     case CGUIEvent::eCutState:
  312.     case CGUIEvent::ePasteState:
  313.     case CGUIEvent::eUndoState:
  314.     case CGUIEvent::eRedoState:
  315.         // editing not yet supported
  316.         break;
  317.     case CGUIEvent::eSelectState:
  318.     case CGUIEvent::eSelectIncState:
  319.         if (signal == CGUIEvent::eSelectSignal) {
  320.             const CLayoutObject* obj = m_Renderer->HitTest(ev_x, h()-ev_y);
  321.             // Distinguish selection and incremental selection
  322.             if (state == CGUIEvent::eSelectState) {
  323.                 m_Renderer->ClearObjectSelection();
  324.             }
  325.             // Save last clicked objects
  326.             if (obj) {
  327.                 const CObject* sel_obj = obj->GetObject( 
  328.                         TSeqPos(m_Renderer->GetFeatGlPane().UnProjectX(ev_x)) );
  329.                 
  330.                 m_LastSelLayoutObj.Reset(obj);
  331.                 SelectObject(sel_obj);
  332.             }
  333.             // double click zooms on the feature/alignment/etc
  334.             if (Fl::event_clicks()) {
  335.                 m_Renderer->ZoomOnObject(obj);
  336.             }
  337.     
  338.             // ping the callback on selection
  339.             if (obj) {
  340.                 parent()->parent()->do_callback(parent()->parent());
  341.             }
  342.             redraw();
  343.         }
  344.         break;
  345.     case CGUIEvent::ePopupState:
  346.         break;
  347.         
  348.     case CGUIEvent::eInsZoomStateIn:
  349.     case CGUIEvent::eInsZoomStateOut:
  350.         m_ZoomingIn = state == CGUIEvent::eInsZoomStateIn;
  351.         x_Handle_TimerZoom();        
  352.         break;
  353.         
  354.     case CGUIEvent::eLensZoomState:
  355.         x_Handle_LensZoom();
  356.         break;
  357.         
  358.     default:
  359.         break;
  360.     }
  361.     // pass events to the tooltip object
  362.     m_Tooltip.Handle(event);
  363.     
  364.     return CGlPaneWidgetChild::handle(event);
  365. }
  366. // called by Fl::add_timeout
  367. void s_CSeqGraphicPane_ZoomTimer(void* parent)
  368. {
  369.     CSeqGraphicPane* pane = (CSeqGraphicPane*)parent;
  370.     if (pane->m_TimerActive) { // still need zoom?
  371.         CGlPane& ref_pane = pane->m_Renderer->GetFeatGlPane();
  372.         TModelPoint ref_point = ref_pane.UnProject(pane->m_TimerX, 
  373.                                 pane->MZHH_GetVPPosByY(pane->m_TimerY));
  374.         TModelUnit scaleX = ref_pane.GetScaleX();
  375.         TModelUnit scaleY = ref_pane.GetScaleY();
  376.         // Zoom In or Zoom Out
  377.         scaleX = pane->m_ZoomingIn ? scaleX / 1.5f : scaleX * 1.5f;
  378.         
  379.         pane->m_Renderer->SetScaleRef(scaleX, scaleY, ref_point);
  380.     
  381.         pane->m_VisibleRangeChanged = true;  // visible range changed    
  382.         pane->redraw();
  383.         if (pane->m_TimerActive) // if still active
  384.             Fl::add_timeout(0.25, s_CSeqGraphicPane_ZoomTimer, parent);
  385.     }
  386. }
  387. void CSeqGraphicPane::x_Handle_TimerZoom()
  388. {
  389.     switch(m_Event.GetFLTKEvent()) {
  390.     case FL_PUSH:
  391.         m_TimerActive = true;
  392.         m_TimerX = Fl::event_x();
  393.         m_TimerY = h() - Fl::event_y();
  394.     
  395.         s_CSeqGraphicPane_ZoomTimer(this);
  396.         break;
  397.     case FL_DRAG:
  398.         m_TimerActive = false;
  399.         break;
  400.         
  401.     case FL_RELEASE:
  402.         m_TimerActive = false;
  403.         break;
  404.     default:
  405.         break;
  406.     } // switch (FLTK event) 
  407. }
  408. void CSeqGraphicPane::x_Handle_LensZoom()
  409. {
  410.     // it will make sence to move the Lens Zoom into separate handler
  411.     // like mouse_scroll_handler
  412.     switch(m_Event.GetFLTKEvent()) {
  413.     case FL_PUSH:
  414.     case FL_DRAG:
  415.         m_Renderer->SetLensZoom(Fl::event_x(), h() - Fl::event_y());
  416.         redraw();
  417.         break;
  418.     case FL_RELEASE:
  419.         m_Renderer->CancelLensZoom();
  420.         redraw();
  421.         break;
  422.     default:
  423.         break;
  424.     } // switch (FLTK event)
  425. }
  426.         
  427. // Place selected objects into clipboard
  428. void CSeqGraphicPane::x_Handle_ClipboardCopy()
  429. {
  430.     CClipboard::Clear();
  431.     // retrieve and process selections
  432.     CScope& scope = m_DS->GetBioseqHandle().GetScope();
  433.     TConstObjects sel_objs =
  434.         m_Renderer->GetSelectedObjects();
  435.     ITERATE (TConstObjects, iter, sel_objs) {
  436.         CObjClipboard::Add(scope, **iter);
  437.     }
  438.     const CSeq_id* id = m_DS->GetBioseqHandle().GetSeqId();
  439.     const TRangeColl& sel_ranges = GetSelectedSeqRanges();
  440.     ITERATE (TRangeColl, iter, sel_ranges) {
  441.         CRef<CSeq_loc> loc(new CSeq_loc());
  442.         loc->SetInt().SetFrom(iter->GetFrom());
  443.         loc->SetInt().SetTo  (iter->GetTo());
  444.         loc->SetId(*id);
  445.         CObjClipboard::Add(scope, *loc);
  446.     }
  447.     CObjClipboard::Copy();
  448. }
  449. /*int CSeqGraphicPane::handle(int event)
  450. {
  451.     case eLensZoomState:
  452.         switch (signal) {
  453.         case CGUIEvent::ePush:
  454.             // unhandled state - we have a few special cases here
  455.             m_Renderer->SetLensZoom(ev_x, h() - ev_y);
  456.             redraw();
  457.             return 1;
  458.         case CGUIEvent::eDrag:
  459.             m_Renderer->SetLensZoom(ev_x, h() - ev_y);
  460.             redraw();
  461.             return 1;
  462.         case CGUIEvent::eRelease:
  463.             m_Renderer->CancelLensZoom();
  464.             redraw();
  465.             return 1;
  466.         default:
  467.             break;
  468.         }
  469.         break;
  470.     case eZoomInState:
  471.         m_Renderer->ZoomInCenter();
  472.         return 1;
  473.     case eZoomOutState:
  474.         m_Renderer->ZoomOutCenter();
  475.         return 1;
  476.     case eZoomInFullState:
  477.         m_Renderer->SetZoomX(0.0f);
  478.         return 1;
  479.     case eZoomOutFullState:
  480.         m_Renderer->SetZoomX(1.0f);
  481.         return 1;
  482.     default:
  483.         break;
  484.     }
  485.     
  486.     // pass events to the tooltip object
  487.     m_Tooltip.Handle(event);
  488.     return CGlCanvas2d::handle(event);
  489. }
  490. */
  491. // IMouseZoomHandlerHost implementation
  492. TModelUnit CSeqGraphicPane::MZHH_GetScale(EScaleType type)
  493. {
  494.     switch(type)    {
  495.     case eCurrent:   return m_Renderer->GetFeatGlPane().GetScaleX();
  496.     case eMin: return m_Renderer->GetFeatGlPane().GetMinScaleX();
  497.     case eMax: return m_Renderer->GetFeatGlPane().GetZoomAllScaleX();
  498.     default: _ASSERT(false); return -1;
  499.     }
  500. }
  501. void CSeqGraphicPane::MZHH_SetScale(TModelUnit scale, const TModelPoint& point) 
  502. {
  503.     m_Renderer->SetScaleRef(scale, m_Renderer->GetFeatGlPane().GetScaleY(),
  504.                             point);
  505.     m_VisibleRangeChanged = true;  // visible range changed
  506.     
  507.     redraw();
  508. }
  509. void CSeqGraphicPane::MZHH_ZoomRect(const TModelRect& rc)
  510. {
  511.     m_VisibleRangeChanged = true;  // visible range changed
  512.     ZoomOnRange( TSeqRange(TSeqPos(rc.Left()), TSeqPos(rc.Right())) );
  513. }
  514. void CSeqGraphicPane::MZHH_Scroll(TModelUnit d_x, TModelUnit d_y)
  515. {
  516.     const TModelRect& rc = m_Renderer->GetFeatGlPane().GetVisibleRect();
  517.     
  518.     Scroll(rc.Left() + d_x, 0);
  519. }
  520. TVPUnit CSeqGraphicPane::MZHH_GetVPPosByY(int y) const
  521. {
  522.     return h() - 1  - y;
  523. }
  524. void CSeqGraphicPane::MZHH_Redraw(void)
  525. {
  526.     redraw();
  527. }
  528. // IMouseZoomHandlerHost end
  529. // IMouseScrollHandlerHost implementation
  530. /*void CSeqGraphicPane::MSHH_Scroll(TVPUnit v_x)
  531. {
  532.     m_Renderer->Scroll(v_x);
  533.     m_VisibleRangeChanged = true;  // visible range changed
  534. }
  535. void CSeqGraphicPane::MSHH_Redraw(void)
  536. {
  537.     redraw();
  538. }*/
  539. // IMouseScrollHandlerHost end
  540. /// ISelHandlerHost implementation
  541. void CSeqGraphicPane::SHH_Redraw()
  542. {
  543.     parent()->parent()->do_callback(parent()->parent());
  544.     
  545.     redraw();
  546. }
  547. TModelUnit CSeqGraphicPane::SHH_GetModelByWindow(int z, EOrientation orient)
  548. {
  549.     switch(orient)  {
  550.     case eHorz: return m_Renderer->GetRulerGlPane().UnProjectX(z);
  551.     case eVert: return m_Renderer->GetRulerGlPane().UnProjectY(h() - z);
  552.     default:    _ASSERT(false); return -1;
  553.     }
  554. }
  555. TVPUnit CSeqGraphicPane::SHH_GetWindowByModel(TModelUnit z, EOrientation orient)
  556. {
  557.     switch(orient)  {
  558.     case eHorz: return m_Renderer->GetRulerGlPane().ProjectX(z);
  559.     case eVert: return h() - m_Renderer->GetRulerGlPane().ProjectY(z);
  560.     default:    _ASSERT(false); return -1;
  561.     }
  562. }
  563. ////////////////////////////////////////////////////////////////////////////////
  564. ///////////////////////////////////////////////////////////////////////////////
  565. /// ITooltip Implementation
  566. /// TC_NeedTooltip() and TC_GetTooltip() is evrything needed to show toolitps
  567. /// in "active" mode
  568. bool CSeqGraphicPane::TC_NeedTooltip(int x, int y)
  569. {
  570.     m_Renderer->GetTooltip(x, h() - y, &m_TooltipText);
  571.     return m_TooltipText.length() > 0;
  572. }
  573. string CSeqGraphicPane::TC_GetTooltip(int& x, int& y, int& w, int& h)
  574. {
  575.     return m_TooltipText;
  576. }
  577. // ITooltip end
  578. // --- Scrolling --------------------------------------------------
  579. void CSeqGraphicPane::Scroll(TModelUnit x, TModelUnit y)
  580. {
  581.     m_Renderer->Scroll(x, y);
  582.     
  583.     m_VisibleRangeChanged = true;  // indicate a visible range change
  584.     redraw();
  585. }
  586. void CSeqGraphicPane::ZoomOnRange(const TSeqRange& range)
  587. {
  588.     m_Renderer->ZoomOnRange(range);
  589. }
  590. TSeqRange CSeqGraphicPane::GetVisibleRange() const
  591. {
  592.     return m_Renderer->GetVisibleRange();
  593. }
  594. bool CSeqGraphicPane::VisibleRangeChanged() const
  595. {
  596.     return m_VisibleRangeChanged;
  597. }
  598. void CSeqGraphicPane::ResetVisibleRangeChanged()
  599. {
  600.     m_VisibleRangeChanged = false;
  601. }
  602. void CSeqGraphicPane::GetFeatureNames(vector<string>& names)
  603. {
  604.     names.clear();
  605.     const CFeatConfigList& feat_list = *GetFeatConfigList();
  606.     ITERATE (CFeatConfigList, iter, feat_list) {
  607.         names.push_back(iter->GetDescription());
  608.     }
  609. }
  610. void CSeqGraphicPane::SetConfig(CRef<CSeqGraphicConfig> config)
  611. {
  612.     m_ConfigSettings = config;
  613.     m_Renderer->SetConfig(m_ConfigSettings);
  614. }
  615.     
  616. void CSeqGraphicPane::UpdateConfig()
  617. {
  618.     m_Renderer->UpdateConfig();
  619.     redraw();
  620. }
  621. // CGlPaneWidgetChild requirements
  622. TVPPoint CSeqGraphicPane::GetPortSize(void) 
  623.     return TVPPoint(0,0); 
  624. }
  625. // Zoom command handlers
  626. void CSeqGraphicPane::ZoomIn(void)
  627. {
  628.     m_Renderer->ZoomInCenter();
  629.     redraw();
  630. }
  631. void CSeqGraphicPane::ZoomOut(void)
  632. {
  633.     m_Renderer->ZoomOutCenter();
  634.     redraw();
  635. }
  636. void CSeqGraphicPane::ZoomAll(void)
  637. {
  638.     m_Renderer->ZoomAll();
  639.     redraw();
  640. }
  641. void CSeqGraphicPane::ZoomObject(void)
  642. {
  643.     if (m_LastSelObj) {
  644.      TSeqRange range = m_LastSelLayoutObj->GetLocation().GetTotalRange();
  645.         ZoomOnRange(range);
  646.         redraw();
  647.     }
  648. }
  649. void CSeqGraphicPane::NextPrevExon(EDirection dir)
  650. {
  651.     if (!m_LastSelObj) return;
  652.     const CLayoutFeat* feat = dynamic_cast<const CLayoutFeat*>(m_LastSelObj.GetPointer());
  653.     if (!feat) return;
  654.    
  655.     TModelRect rc = m_Renderer->GetFeatGlPane().GetVisibleRect();
  656.     TSeqPos center_x = TSeqPos( rc.CenterPoint().X() );
  657.     TSeqPos d_x = INT_MAX;
  658.     ITERATE (vector<TSeqRange>, iter, feat->GetIntervals()) {
  659.         const TSeqRange& curr = *iter;
  660.         if (dir == eNext) { // Next exon
  661.             if (curr.GetFrom() > center_x) 
  662.                 d_x = min(d_x, curr.GetFrom() - center_x);
  663.             if (curr.GetTo() > center_x) 
  664.                 d_x = min(d_x, curr.GetTo() - center_x);
  665.         } 
  666.         if (dir == ePrev) { // Prev exon
  667.             if (center_x > curr.GetFrom())
  668.                 d_x = min(d_x, center_x - curr.GetFrom());
  669.             if (center_x > curr.GetTo())
  670.                 d_x = min(d_x, center_x - curr.GetTo());
  671.         }
  672.     }
  673.     if (d_x > 0  &&  d_x < INT_MAX) { // need scroll
  674.         if (dir == eNext)
  675.             Scroll(rc.Left() + d_x, 0);
  676.         if (dir == ePrev)
  677.             Scroll(rc.Left() - d_x, 0);
  678.             
  679.         redraw();
  680.     }
  681. }
  682. void CSeqGraphicPane::x_OnShowPopup() 
  683.     if (m_ParentWidget) {
  684.         m_ParentWidget->OnShowPopup(); 
  685.     }
  686. }
  687. // handlers specific implementation
  688. int CSeqGraphicPane::x_GetAreaByMousePos()
  689. {
  690.     int vp_x = Fl::event_x();
  691.     int vp_y = h() - Fl::event_y();
  692.     const TVPRect& rc_zoom   = m_Renderer->GetFeatGlPane().GetViewport();
  693.     const TVPRect& rc_select = m_Renderer->GetRulerGlPane().GetViewport();
  694.     // Deside where the mouse is:
  695.     if(rc_zoom.PtInRect(vp_x, vp_y)) {
  696.         return fFeaturesArea;
  697.     } else if(rc_select.PtInRect(vp_x, vp_y)) {
  698.         return fSeqRulerArea;
  699.     }
  700.     return fOther;
  701. }
  702. END_NCBI_SCOPE
  703. /*
  704.  * ===========================================================================
  705.  * $Log: seqgraphic_pane.cpp,v $
  706.  * Revision 1000.2  2004/06/01 21:12:53  gouriano
  707.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.31
  708.  *
  709.  * Revision 1.31  2004/05/21 22:27:55  gorelenk
  710.  * Added PCH ncbi_pch.hpp
  711.  *
  712.  * Revision 1.30  2004/05/10 15:06:32  lebedev
  713.  * Offset HTML Active areas by the height of the ruler bar
  714.  *
  715.  * Revision 1.29  2004/05/07 15:43:36  dicuccio
  716.  * Use CObjClipboard
  717.  *
  718.  * Revision 1.28  2004/05/03 13:23:58  dicuccio
  719.  * gui/utils --> gui/objutils where needed
  720.  *
  721.  * Revision 1.27  2004/04/19 15:43:21  lebedev
  722.  * Code cleanup
  723.  *
  724.  * Revision 1.26  2004/04/16 14:53:04  dicuccio
  725.  * Pass objects using TConstObjects, not TObjSelections.  Added ISelection
  726.  * interfaces.
  727.  *
  728.  * Revision 1.25  2004/04/15 13:02:13  lebedev
  729.  * HitTesting for LayoutObjects changed
  730.  *
  731.  * Revision 1.24  2004/04/12 18:48:34  dicuccio
  732.  * Removed five pixel border from the graphical view
  733.  *
  734.  * Revision 1.23  2004/04/07 13:12:19  dicuccio
  735.  * Split GetAnnotSelector() API for features to use feature sbtype separately from
  736.  * feature type
  737.  *
  738.  * Revision 1.22  2004/04/06 13:45:31  dicuccio
  739.  * Formatting changes
  740.  *
  741.  * Revision 1.21  2004/03/23 12:33:56  lebedev
  742.  * Made sequence and histograms bars a layout objects in the object panel.
  743.  * Made segment map a number of layout objects. Get rid of fixed size rows in the object panel.
  744.  *
  745.  * Revision 1.20  2004/03/12 15:59:00  lebedev
  746.  * Command handlers for zooming and feature navigation added.
  747.  *
  748.  * Revision 1.19  2004/03/11 17:53:06  dicuccio
  749.  * Deprecated typedefs TPosition, TDimension, TIndex, TColor.  Use TSeqRange instead of TRange
  750.  *
  751.  * Revision 1.18  2004/03/08 17:00:03  lebedev
  752.  * Zooming clicking and holding the mouse button added. 'I' key to zoom in and
  753.  * 'Shift-I' key to zoom out.
  754.  *
  755.  * Revision 1.17  2004/03/05 18:04:35  ucko
  756.  * Revert previous revision, as eLensZoomState has now materialized.
  757.  *
  758.  * Revision 1.16  2004/03/05 03:02:46  ucko
  759.  * Don't try to use CGUIEvent::eLensZoomState, which hasn't yet been defined....
  760.  *
  761.  * Revision 1.15  2004/03/04 14:38:57  lebedev
  762.  * Avoid event handlers conflicts by inheriting from CGlPaneWidgetChild.
  763.  * Support for new mouse scroll handler added. Re-enable lens zoom (L key).
  764.  *
  765.  * Revision 1.14  2004/02/27 15:51:22  lebedev
  766.  * Correctly handle eSelectState
  767.  *
  768.  * Revision 1.13  2004/02/13 18:11:32  lebedev
  769.  * Use SeqGraphic config for enabling/disabling viewing options
  770.  *
  771.  * Revision 1.12  2004/02/10 13:15:33  lebedev
  772.  * ISelHandlerHost interface implemented for selections on sequence pane
  773.  *
  774.  * Revision 1.11  2004/02/04 14:33:00  dicuccio
  775.  * Return 1 from all handled events in handle()
  776.  *
  777.  * Revision 1.10  2004/02/03 16:54:43  dicuccio
  778.  * Event handler clean-up.  Dropped explicit handling of zomm events in favor of
  779.  * IMouseEventHandler interface functions
  780.  *
  781.  * Revision 1.9  2004/01/30 21:10:01  dicuccio
  782.  * Reworked event loop to use CGUIEvent entirely.  Added handling of
  783.  * copy-to-clipboard
  784.  *
  785.  * Revision 1.8  2004/01/28 14:10:00  lebedev
  786.  * Indicate a visible range change where needed
  787.  *
  788.  * Revision 1.7  2004/01/27 16:14:19  lebedev
  789.  * Changed stored selection from CLayoutObject to CObject
  790.  *
  791.  * Revision 1.6  2004/01/20 20:35:30  rsmith
  792.  * Add UpdateConfig method to notify classes when the configuration object has changed.
  793.  *
  794.  * Revision 1.5  2004/01/20 14:08:44  rsmith
  795.  * CFeatConfigList knows about feature descriptions and types, not the configuration object.
  796.  *
  797.  * Revision 1.4  2004/01/16 13:40:15  lebedev
  798.  * Tooltips added
  799.  *
  800.  * Revision 1.3  2004/01/05 21:24:28  dicuccio
  801.  * Code clean-up.  Removed dead code.
  802.  *
  803.  * Revision 1.2  2003/12/29 14:54:13  rsmith
  804.  * config classes no longer contain the list of feature types. Use GetFeatConfigList()
  805.  *
  806.  * Revision 1.1  2003/12/22 12:59:00  lebedev
  807.  * Files renamed
  808.  *
  809.  * Revision 1.60  2003/12/16 18:55:26  lebedev
  810.  * ScaleRefPoint implementation fixed (do not project reference point into model space)
  811.  *
  812.  * Revision 1.59  2003/12/10 17:00:43  yazhuk
  813.  * Updated implementation of  IMouseZoomHandlerHost interface.
  814.  *
  815.  * Revision 1.58  2003/12/09 12:39:59  lebedev
  816.  * Implemented IMouseZoomHandlerHost interface for zooming and scrolling with mouse
  817.  * ===========================================================================
  818.  */