NCBI C++ ToolKit
phylo_tree_pane.cpp
Go to the documentation of this file.
00001 /*  $Id: phylo_tree_pane.cpp 25384 2012-03-06 19:27:20Z ucko $
00002  * ===========================================================================
00003  *
00004  *                            PUBLIC DOMAIN NOTICE
00005  *               National Center for Biotechnology Information
00006  *
00007  *  This software/database is a "United States Government Work" under the
00008  *  terms of the United States Copyright Act.  It was written as part of
00009  *  the author's official duties as a United States Government employee and
00010  *  thus cannot be copyrighted.  This software/database is freely available
00011  *  to the public for use. The National Library of Medicine and the U.S.
00012  *  Government have not placed any restriction on its use or reproduction.
00013  *
00014  *  Although all reasonable efforts have been taken to ensure the accuracy
00015  *  and reliability of the software and data, the NLM and the U.S.
00016  *  Government do not and cannot warrant the performance or results that
00017  *  may be obtained by using this software or data. The NLM and the U.S.
00018  *  Government disclaim all warranties, express or implied, including
00019  *  warranties of performance, merchantability or fitness for any particular
00020  *  purpose.
00021  *
00022  *  Please cite the author in any work or product based on this material.
00023  *
00024  * ===========================================================================
00025  *
00026  * Authors:  Vladimir Tereshkov
00027  *
00028  * File Description: 
00029  *
00030  */
00031 
00032 #include <ncbi_pch.hpp>
00033 #include <corelib/ncbitime.hpp>
00034 
00035 #include <gui/widgets/phylo_tree/phylo_tree_pane.hpp>
00036 #include <gui/widgets/phylo_tree/phylo_tree_widget.hpp>
00037 #include <gui/widgets/phylo_tree/phylo_tree_pane.hpp>
00038 
00039 #include <gui/widgets/gl/attrib_menu.hpp>   
00040 #include <gui/objutils/registry.hpp>
00041 #include <gui/opengl/glutils.hpp>
00042 #include <corelib/ncbitime.hpp>
00043 
00044 #include <wx/wxchar.h>
00045 #include <wx/dcclient.h>
00046 
00047 BEGIN_NCBI_SCOPE
00048 
00049 #define AXIS_AREA_W 50
00050 #define AXIS_AREA_H 30
00051 
00052 
00053 BEGIN_EVENT_TABLE(CPhyloTreePane, CGlWidgetPane)
00054     EVT_SIZE(CPhyloTreePane::OnSize)
00055     EVT_LEFT_DOWN(CPhyloTreePane::OnLeftDown)
00056     EVT_PAINT(CPhyloTreePane::OnPaint)
00057 END_EVENT_TABLE()
00058 
00059 CPhyloTreePane::CPhyloTreePane(CPhyloTreeWidget * parent)
00060 :   CGlWidgetPane(parent->GetTopLevelPanel(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0),
00061     m_CurrRenderer(-1),
00062     m_pParent(parent),
00063     m_BackColor(0.95f, 1.0f, 0.95f),
00064     m_pTextFont(NULL),
00065     m_pLblFont(NULL),
00066     m_VertSelHandler(eVert),
00067     m_BottomRuler(true),
00068     m_TopRuler(true),
00069     m_LeftRuler(false),
00070     m_RightRuler(false),
00071     m_MouseLeftDownEvent(true)
00072 {
00073     m_Renderers.clear();
00074     m_Gen.SetIntegerMode(true, true);
00075     m_Gen.EnableOneBased(true, true);
00076     m_Grid.EnableIntegerCentering(true);
00077 
00078     m_pTextFont = new CGlBitmapFont(CGlBitmapFont::eHelvetica12);
00079     m_pLblFont = new CGlBitmapFont(CGlBitmapFont::eHelvetica10);
00080 
00081     m_TooltipManager.SetHost(static_cast<IStickyTooltipHandlerHost*>(this));
00082     x_RegisterHandler(dynamic_cast<IGlEventHandler*>(&m_TooltipManager),
00083         fMatrixArea, &m_MatrixPane);
00084 
00085     m_MouseZoomHandler.SetHost(static_cast<IMouseZoomHandlerHost*>(this));
00086     x_RegisterHandler(dynamic_cast<IGlEventHandler*>(&m_MouseZoomHandler),
00087         fMatrixArea, &m_MatrixPane);
00088 
00089     m_MinimapHandler.SetHost(static_cast<IMinimapHandlerHost*>(this));
00090     x_RegisterHandler(dynamic_cast<IGlEventHandler*>(&m_MinimapHandler),
00091         fMatrixArea, &m_MatrixPane);
00092 
00093     x_Layout();
00094     x_SetupAxes();
00095 
00096     CGuiRegistry& gui_reg = CGuiRegistry::GetInstance();
00097 
00098     CGuiRegistry::TReadView view =
00099             gui_reg.GetReadView("GBENCH.Mouse.ModePhylo");
00100 
00101     std::string pan_mode = view.GetString("Pan");
00102     if (pan_mode == "lmouse") {
00103         m_MouseZoomHandler.SetPanMode(CMouseZoomHandler::eLmouse);
00104     }
00105     else {
00106         m_MouseZoomHandler.SetPanMode(CMouseZoomHandler::ePkey);
00107     }
00108 }
00109 
00110 CPhyloTreePane::~CPhyloTreePane()
00111 {
00112     // delete all installed renderers
00113     ITERATE(TRenderers, rr, m_Renderers) {
00114         delete *rr;
00115     }
00116     m_Renderers.clear(); 
00117 }
00118 
00119 
00120 void    CPhyloTreePane::x_SetupAxes()
00121 {
00122     m_TopRuler.SetHorizontal(true, CRuler::eTop);
00123     m_RightRuler.SetHorizontal(false, CRuler::eRight);
00124 }
00125 
00126 
00127 TVPPoint CPhyloTreePane::GetPortSize(void)
00128 {
00129     return TVPPoint(m_rcMatrix.Width(), m_rcMatrix.Height());
00130 }
00131 
00132 void CPhyloTreePane::UpdatePane(const TModelRect& r)
00133 {
00134     m_MatrixPane.SetModelLimitsRect(r);
00135     m_MatrixPane.SetVisibleRect(r);
00136     m_MatrixPane.AdjustToLimits();
00137 }
00138 
00139 void CPhyloTreePane::RemoveCurrentDataSource()
00140 {
00141     // This is for the purpose of cancelling any background jobs
00142     // dependent on the data source.  We do not re-display base don this.
00143     if (m_CurrRenderer>=0) {
00144         GetCurrRenderer()->RemoveCurrentDataSource();
00145     }
00146 }
00147 
00148 void CPhyloTreePane::UpdateDataSource()
00149 {
00150     if (m_CurrRenderer>=0) {
00151         GetCurrRenderer()->UpdateDataSource(*x_GetParent()->GetDS(), m_MatrixPane);
00152     }
00153 }
00154 
00155 void    CPhyloTreePane::OnSize(wxSizeEvent& event)
00156 {
00157     x_Layout();
00158 
00159     event.Skip();
00160 }
00161 
00162 
00163 void    CPhyloTreePane::x_Render(void)
00164 {    
00165     if (m_MatrixPane.GetProjMode()!=CGlPane::eNone) {
00166         // recursive call - something wrong or renderer crashed
00167         //m_MatrixPane.Close();
00168         return;
00169     }
00170     x_RenderContent();
00171 }
00172 
00173 
00174 void    CPhyloTreePane::x_OnShowPopup()
00175 {
00176     x_GetParent()->OnShowPopup();
00177 }
00178 
00179 
00180 void    CPhyloTreePane::Update()
00181 {
00182     _ASSERT(x_GetParent());
00183 
00184     if (m_CurrRenderer>=0 && x_GetParent() && x_GetParent()->GetDS()) {
00185         x_SetupGLContext();
00186         GetCurrRenderer()->Layout(*x_GetParent()->GetDS(), m_MatrixPane);
00187         m_NavHistory.Reset(m_MatrixPane);
00188 
00189       
00190         x_GetParent()->SetPortLimits(m_MatrixPane.GetModelLimitsRect(), true);
00191     }
00192 }
00193 
00194 
00195 void    CPhyloTreePane::SoftUpdate()
00196 {
00197     _ASSERT(x_GetParent());
00198 
00199     if (m_CurrRenderer>=0 && x_GetParent() && x_GetParent()->GetDS()) {
00200         GetCurrRenderer()->Layout(*x_GetParent()->GetDS(), m_MatrixPane);
00201         m_NavHistory.Reset(m_MatrixPane);
00202         x_GetParent()->SetPortLimits(m_MatrixPane.GetModelLimitsRect(), false);
00203     }
00204 }
00205 
00206 const CPhyloTreePane::TRangeColl & CPhyloTreePane::GetSubjectSelection() const
00207 {
00208     return m_HorzSelHandler.GetSelection();
00209 }
00210 
00211 
00212 const CPhyloTreePane::TRangeColl & CPhyloTreePane::GetQuerySelection() const
00213 {
00214     return m_VertSelHandler.GetSelection();
00215 }
00216 
00217 
00218 CGlPane CPhyloTreePane::TreeNavHistory::Current() const
00219 { 
00220     return Empty() ? CGlPane() : m_History[m_BackForwardPos]; 
00221 }
00222 
00223 bool CPhyloTreePane::TreeNavHistory::EqualPanes(const CGlPane& lhs, const CGlPane& rhs) const
00224 {
00225     // compute roughly the pct scrolling that has taken place in order
00226     // to ignore very (imperceptibly) small changes
00227     TModelRect l = lhs.GetVisibleRect();
00228     TModelRect r = rhs.GetVisibleRect();
00229 
00230     float delta = fabs(l.Left() - r.Left()) +
00231                   fabs(l.Right() - r.Right()) +
00232                   fabs(l.Top() - r.Top()) +
00233                   fabs(l.Bottom() - r.Bottom());
00234 
00235     float m = l.Width() + l.Height() + r.Width() + r.Height();
00236 
00237     float delta_pct = delta/m;
00238 
00239     return delta_pct < 0.0001f;        
00240 }
00241 
00242 void CPhyloTreePane::TreeNavHistory::Reset(const CGlPane& p) 
00243 {
00244     m_History.clear(); 
00245     m_History.push_back(p); 
00246     m_BackForwardPos = 0;
00247 }
00248 
00249 void CPhyloTreePane::TreeNavHistory::Add(const CGlPane& p) 
00250 {
00251     if (m_BackForwardPos < m_History.size()) {
00252         m_History.erase(m_History.begin() + m_BackForwardPos +1,
00253                         m_History.end());
00254     }
00255   
00256     m_History.push_back(p);
00257     m_BackForwardPos = m_History.size() - 1;
00258 }
00259 
00260 void CPhyloTreePane::SaveCurrentView()
00261 {
00262     if (m_NavHistory.Empty() || 
00263         !m_NavHistory.EqualPanes(x_GetParent()->GetPort(), m_NavHistory.Current())) {
00264             m_NavHistory.Add(x_GetParent()->GetPort());
00265     }
00266 }
00267 
00268 bool CPhyloTreePane::CanGoBack() const
00269 {
00270     return m_NavHistory.CanGoBack();
00271 }
00272 
00273 
00274 bool CPhyloTreePane::CanGoForward() const
00275 {
00276     return m_NavHistory.CanGoForward();
00277 }
00278 
00279 
00280 void CPhyloTreePane::GoBack(void)
00281 {
00282     if (CanGoBack()) {
00283         CGlPane p = m_NavHistory.Back();
00284         //m_MatrixPane = p;
00285         m_MatrixPane.SetVisibleRect(p.GetVisibleRect());
00286         m_MatrixPane.SetModelLimitsRect(p.GetModelLimitsRect());
00287         x_GetParent()->GetPort().SetModelLimitsRect(m_MatrixPane.GetModelLimitsRect());
00288         x_GetParent()->GetPort().SetVisibleRect(m_MatrixPane.GetVisibleRect());
00289         x_GetParent()->UpdateViewingArea();
00290         x_GetParent()->Refresh();
00291     }
00292 }
00293 
00294 
00295 void CPhyloTreePane::GoForward(void)
00296 {
00297     if (CanGoForward()) {
00298         CGlPane p = m_NavHistory.Forward();
00299         //m_MatrixPane = p;
00300         m_MatrixPane.SetVisibleRect(p.GetVisibleRect());
00301         m_MatrixPane.SetModelLimitsRect(p.GetModelLimitsRect());
00302         x_GetParent()->GetPort().SetVisibleRect(m_MatrixPane.GetVisibleRect());
00303         x_GetParent()->UpdateViewingArea();
00304         x_GetParent()->Refresh();
00305     }
00306 }
00307 
00308 
00309 void CPhyloTreePane::x_Layout(void)
00310 {
00311     TModelRect vis = m_MatrixPane.GetVisibleRect();
00312     m_rcMatrix.Init(0, 0, GetClientSize().GetWidth(), GetClientSize().GetHeight());    
00313     m_MatrixPane.SetViewport(m_rcMatrix);
00314 
00315     if (m_CurrRenderer >= 0 && x_GetParent()->GetDS() != NULL) {
00316         m_MatrixPane.SetVisibleRect(vis);
00317         GetCurrRenderer()->ComputeViewingLimits(m_MatrixPane);
00318         x_GetParent()->SetPortLimits(m_MatrixPane.GetModelLimitsRect(), false);
00319     }
00320 
00321     m_NavHistory.Reset(m_MatrixPane);
00322 }
00323 
00324 void    CPhyloTreePane::SetupHardcopyRender()
00325 {
00326     if (m_CurrRenderer >= 0  &&
00327         m_CurrRenderer < (int)m_Renderers.size() &&
00328         x_GetParent()->GetDS()){
00329         m_Renderers[m_CurrRenderer]->ComputeViewingLimits(
00330             m_MatrixPane, false);
00331     }
00332 }
00333 
00334 void CPhyloTreePane::RenderCurrent(void)
00335 {
00336     if (m_CurrRenderer >= 0  &&
00337         m_CurrRenderer < (int)m_Renderers.size() &&
00338         x_GetParent()->GetDS()){
00339         m_Renderers[m_CurrRenderer]->RenderForHardcopy(
00340             m_MatrixPane, *x_GetParent()->GetDS());
00341     }
00342 }
00343 
00344 void CPhyloTreePane::BufferedRender(void)
00345 {
00346     if (m_CurrRenderer >= 0  &&
00347         m_CurrRenderer < (int)m_Renderers.size() &&
00348         x_GetParent()->GetDS()){
00349         m_Renderers[m_CurrRenderer]->BufferedRender(
00350             m_MatrixPane, *x_GetParent()->GetDS());
00351     }
00352 }
00353 
00354 // We override the base class version only because we want to be
00355 // able to Not call SwapBuffers() since x_Render() will sometimes
00356 // not draw because synchronization is in progress in
00357 // the particle system thread.  And if you don't draw, you can't 
00358 // call SwapBuffers().
00359 void CPhyloTreePane::OnPaint( wxPaintEvent& WXUNUSED(event) )
00360 {
00361     //LOG_POST("CGLCanvas::OnPaint()");
00362 
00363     // This is a dummy, to avoid an endless succession of paint messages.
00364     // OnPaint handlers must always create a wxPaintDC.
00365     wxPaintDC dc(this);
00366 
00367     // The hack is used for tooltip window
00368     // SwapBuffers ovewrites child windows on some systems
00369     // Ubuntu with Intel videocard (netbook).
00370     if (m_DoNotUpdate) {
00371         m_DoNotUpdate = false;
00372         return;
00373     }
00374 
00375     x_SetupGLContext();
00376     x_Render();
00377 
00378     // Move swapbuffers() to x_Render() and only call
00379     // it if the rendering is actually completed.
00380 }
00381 
00382 void    CPhyloTreePane::x_RenderContent(void)
00383 {
00384     if(x_GetParent()) {
00385         CStopWatch sw;
00386         sw.Start();
00387 
00388         CRgbaColor bg(1.0f, 1.0f, 1.0f, 1.0f);
00389         if (x_GetParent()->HasScheme())
00390             bg = x_GetParent()->GetScheme().SetColor(
00391                 CPhyloTreeScheme::eTree, CPhyloTreeScheme::eBgColor);
00392         glClearColor(bg.GetRed(), bg.GetGreen(), bg.GetBlue(), bg.GetAlpha());    
00393         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
00394 
00395         // Make sure layout has been called (special case for first-time render
00396         // of newly created view)
00397         if (m_CurrRenderer >= 0  &&
00398             m_CurrRenderer < (int)m_Renderers.size() &&
00399             x_GetParent()->GetDS()){
00400                 if ( m_Renderers[m_CurrRenderer]->ValidLayout() == 
00401                      IPhyloTreeRenderer::eNeedLayout ) 
00402                     SoftUpdate();
00403                 else if ( m_Renderers[m_CurrRenderer]->ValidLayout() == 
00404                           IPhyloTreeRenderer::eNeedLayoutAndSize ) 
00405                     Update();
00406         }
00407 
00408         const CGlPane& VP = x_GetParent()->GetPort();
00409 
00410         // prepare CGlPanes
00411 
00412         // The limits rect is set in Layout() and OnSize().  But
00413         // we need updates to the visible rect since it captures
00414         // zoom.  Not sure why the design called for a CGlPane in
00415         // both this (CPhyloTreePane) and CPhyloTreeWidget, forcing
00416         // us to keep them in sync.....
00417         TModelRect rc_V = VP.GetVisibleRect();
00418         m_MatrixPane.SetVisibleRect(rc_V);
00419         m_MatrixPane.SetModelLimitsRect( VP.GetModelLimitsRect() );
00420 
00421         // now rendering
00422 
00423         if (m_CurrRenderer >= 0  &&
00424             m_CurrRenderer < (int)m_Renderers.size() &&
00425             x_GetParent()->GetDS()){
00426 
00427                 /// Stop rendering if Render() returns false (can return false
00428                 /// in force layout due to active data synchronization)
00429                 if (!m_Renderers[m_CurrRenderer]->Render(
00430                     m_MatrixPane, *x_GetParent()->GetDS())) {
00431                         return;
00432                 }           
00433         }
00434 
00435         x_RenderMouseZoomHandler(m_MatrixPane);
00436 #ifdef ATTRIB_MENU_SUPPORT
00437         CAttribMenuInstance::GetInstance().DrawMenu();
00438 #endif
00439 
00440 
00441     }
00442 
00443     if (m_MouseLeftDownEvent) {
00444          m_MouseLeftDownEvent= false;
00445          m_TooltipManager.ParentShow(false);
00446          m_TooltipManager.ParentShow(true);
00447     }
00448 
00449     // Move swapbuffers code from glcanvas basecalss to here because
00450     // Render() may return false from the force layout in which case
00451     // it returns before reaching here.
00452 #if defined __WXMSW__
00453     ShowCursor(false);
00454 #endif
00455 
00456     SwapBuffers();
00457 
00458 #if defined __WXMSW__
00459     ShowCursor(true);
00460 #endif
00461 }
00462 
00463 
00464 void    CPhyloTreePane::x_AdjsutToMasterPane(CGlPane& pane,
00465                                              bool b_model_x,
00466                                              bool b_model_y)
00467 {
00468     const CGlPane& VP = x_GetParent()->GetPort();
00469 
00470     TModelRect rc_vis = VP.GetVisibleRect();
00471     TModelRect rc_lim = VP.GetModelLimitsRect();
00472 
00473     // assuming that Viewport in the pane has been set properly
00474     if(! b_model_x) { // adjust horz range to represent pixels
00475         int max_x = pane.GetViewport().Width() - 1;
00476         rc_lim.SetHorz(0, max_x);
00477         rc_vis.SetHorz(0, max_x);
00478     }
00479 
00480     if(! b_model_y) { // adjust vert range to represent pixels
00481         int max_y = pane.GetViewport().Height() - 1;
00482         rc_lim.SetVert(0, max_y);
00483         rc_vis.SetVert(0, max_y);
00484     }
00485     pane.SetModelLimitsRect(rc_lim);
00486     pane.SetVisibleRect(rc_vis);
00487 }
00488 
00489 int     CPhyloTreePane::x_GetAreaByVPPos(TVPUnit vp_x, TVPUnit vp_y)
00490 {
00491     if(m_rcMatrix.PtInRect(vp_x, vp_y)) {
00492         return fMatrixArea;
00493     } else if(m_rcBottomSeq.PtInRect(vp_x, vp_y)) {
00494         return fSubjectArea;
00495     } else if(m_rcLeftSeq.PtInRect(vp_x, vp_y)) {
00496         return fQueryArea;
00497     }
00498     return fOther;
00499 }
00500 
00501 void    CPhyloTreePane::x_RenderMouseZoomHandler(CGlPane& pane)
00502 {
00503     glEnable(GL_BLEND);
00504     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00505 
00506     m_MouseZoomHandler.Render(pane);
00507     m_MinimapHandler.Render(pane);
00508 
00509 
00510     glDisable(GL_BLEND);
00511 }
00512 
00513 void    CPhyloTreePane::x_RenderSelHandler(bool b_horz,
00514                                            CGlPane& pane,
00515                                            CLinearSelHandler::ERenderingOption option)
00516 {
00517     glEnable(GL_BLEND);
00518     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00519 
00520     CLinearSelHandler& handler = b_horz ? m_HorzSelHandler : m_VertSelHandler;
00521     handler.Render(pane, option);
00522 
00523     glDisable(GL_BLEND);
00524 
00525 }
00526 
00527 bool CPhyloTreePane::x_GrabFocus()
00528 {
00529     // Grab the focus unless user is in a text control.  This is primarly here
00530     // for the case where the user is typing in the search control, and may use
00531     // the mouse to move the cursor around.  We do not want to lose focus for
00532     // the text control in this case.
00533     if ( CGlWidgetPane::x_GrabFocus() )
00534         return true;
00535 
00536     return false;
00537 
00538     // Maybe not - I think you only want to take focus from certain controls, 
00539     // such as maybe those (other than the text edit control) in the search bar.
00540     /*
00541     wxWindow* w = wxWindow::FindFocus();
00542 
00543     if (w != NULL) {
00544         //_TRACE("Focus Parent: " << w->GetClassInfo()->GetClassName()    << " " << w->GetName());
00545     
00546         if (wxString(w->GetClassInfo()->GetClassName()) == wxT("wxTextCtrl") ||
00547             wxString(w->GetClassInfo()->GetClassName()) == wxT("wxRichTextCtrl") ||
00548             wxString(w->GetClassInfo()->GetClassName()) == wxT("wxComboBox"))
00549             return false;
00550     }    
00551 
00552     return true;    
00553     */
00554 }
00555 ////////////////////////////////////////////////////////////////////////////////
00556 /// IAlnMarkHandlerHost implementation
00557 
00558 TModelUnit  CPhyloTreePane::MZHH_GetScale(EScaleType type)
00559 {
00560     const CGlPane& VP = x_GetParent()->GetPort();
00561 
00562     switch(type)    {
00563     case IMouseZoomHandlerHost::eCurrent:   {
00564         return x_GetParent()->GetScheme().GetZoomBehavior()==CPhyloTreeScheme::eZoomY ?
00565             VP.GetScaleY() : VP.GetScaleX();
00566     }
00567     case IMouseZoomHandlerHost::eMin: {
00568         return x_GetParent()->GetScheme().GetZoomBehavior()==CPhyloTreeScheme::eZoomY?
00569             VP.GetMinScaleY() : VP.GetMinScaleX();
00570     }
00571     case IMouseZoomHandlerHost::eMax:  {
00572         return x_GetParent()->GetScheme().GetZoomBehavior()==CPhyloTreeScheme::eZoomY?
00573             VP.GetZoomAllScaleY() : VP.GetZoomAllScaleX();
00574     }
00575     default: _ASSERT(false); return -1;
00576     }
00577 }
00578 
00579 void    CPhyloTreePane::MZHH_SetScale(TModelUnit scale,
00580                                       const TModelPoint& point)
00581 {
00582     x_GetParent()->OnSetScaleXY(scale, point);
00583 }
00584 
00585 void     CPhyloTreePane::MZHH_ZoomRect(const TModelRect& rc)
00586 {
00587     x_GetParent()->ZoomRect(rc);
00588 }
00589 
00590 
00591 void     CPhyloTreePane::MZHH_ZoomPoint(const TModelPoint& point,
00592                                         TModelUnit factor)
00593 {
00594     x_GetParent()->ZoomPoint(point, factor);
00595 }
00596 
00597 
00598 void     CPhyloTreePane::MZHH_EndOp()
00599 {
00600     SaveCurrentView();
00601 }
00602 
00603 
00604 void     CPhyloTreePane::MZHH_Scroll(TModelUnit d_x, TModelUnit d_y)
00605 {
00606     x_GetParent()->Scroll(d_x, d_y);
00607 }
00608 
00609 
00610 TVPUnit  CPhyloTreePane::MZHH_GetVPPosByY(int y) const
00611 {
00612     return GetClientSize().GetHeight() - 1  - y;
00613 }
00614 
00615 
00616 
00617 
00618 
00619 TVPUnit  CPhyloTreePane::HMGH_GetVPPosByY(int y) const
00620 {
00621     return GetClientSize().GetHeight() - 1  - y;
00622 }
00623 
00624 
00625 
00626 void    CPhyloTreePane::HMGH_UpdateLimits(bool force_redraw)
00627 {
00628     _ASSERT(x_GetParent());
00629 
00630     if (m_CurrRenderer>=0 && x_GetParent() && x_GetParent()->GetDS()) {       
00631         x_GetParent()->GetPort().SetModelLimitsRect(m_MatrixPane.GetModelLimitsRect());
00632         x_GetParent()->GetPort().SetVisibleRect(m_MatrixPane.GetVisibleRect());
00633         x_GetParent()->UpdateViewingArea();            
00634 
00635         if ( force_redraw) {
00636             x_GetParent()->Refresh();
00637         }
00638 
00639         m_NavHistory.Reset(m_MatrixPane);
00640     }
00641 }
00642 
00643 
00644 
00645 ////////////////////////////////////////////////////////////////////////////////
00646 /// ISelHandlerHost implementation
00647 
00648 
00649 void CPhyloTreePane::SHH_OnChanged()
00650 {
00651     CEvent evt(CEvent::eEvent_Message, CViewEvent::eWidgetSelectionChanged);
00652     Send(&evt, ePool_Parent);
00653     
00654     Refresh();
00655 }
00656 
00657 void CPhyloTreePane::SHH_SetCursor(const wxCursor& cursor)
00658 {
00659     SetCursor(cursor);
00660 }
00661 
00662 
00663 TModelUnit  CPhyloTreePane::SHH_GetModelByWindow(int z, EOrientation orient)
00664 {
00665     switch(orient)  {
00666     case eHorz: return m_MatrixPane.UnProjectX(z);
00667     case eVert: return m_MatrixPane.UnProjectY(GetClientSize().GetHeight() - z);
00668     default:    _ASSERT(false); return -1;
00669     }
00670 }
00671 
00672 
00673 TVPUnit     CPhyloTreePane::SHH_GetWindowByModel(TModelUnit z, EOrientation orient)
00674 {
00675     switch(orient)  {
00676     case eHorz: return m_MatrixPane.ProjectX(z);
00677     case eVert: return GetClientSize().GetHeight() - m_MatrixPane.ProjectY(z);
00678     default:    _ASSERT(false); return -1;
00679     }
00680 }
00681 
00682 
00683 void CPhyloTreePane::AddRenderer(IPhyloTreeRenderer * renderer)
00684 {
00685     renderer->SetZoomHandler(&m_MouseZoomHandler);
00686     renderer->SetFont(m_pLblFont);
00687     renderer->SetSimplification(false);
00688     renderer->SetAdaptiveMargins(true);
00689     //renderer->SetSplinesRendering(true);
00690     renderer->SetRegenerateTexture(true);
00691     renderer->SetZoomablePrimitives(false);
00692     renderer->SetRenderingOption(IPhyloTreeRenderer::eAutofitLabels, true);
00693 
00694     m_Renderers.push_back(renderer);
00695 
00696     renderer->SetHost(static_cast<IPhyloTreeRendererHost*>(this));
00697 
00698     if (m_CurrRenderer<0) SetCurrRendererIdx(0);
00699 }
00700 
00701 
00702 void CPhyloTreePane::SetCurrRendererIdx(Int4 idx)
00703 {
00704     if (m_CurrRenderer != idx) {
00705         if (m_CurrRenderer>=0) {
00706             x_UnregisterHandler(dynamic_cast<IGlEventHandler*>(GetCurrRenderer()));
00707         }
00708 
00709         if (m_CurrRenderer >= 0)
00710             m_Renderers[m_CurrRenderer]->StartRendering(false);
00711         m_CurrRenderer = idx;
00712         m_Renderers[m_CurrRenderer]->StartRendering(true);
00713 
00714         if (m_MouseZoomHandler.GetPanMode() == CMouseZoomHandler::eLmouse) {
00715             x_RegisterHandler(dynamic_cast<IGlEventHandler*>(GetCurrRenderer()),
00716                 fMatrixArea, &m_MatrixPane, 1);
00717         }
00718         else {
00719             x_RegisterHandler(dynamic_cast<IGlEventHandler*>(GetCurrRenderer()),
00720                 fMatrixArea, &m_MatrixPane);
00721         }
00722     }
00723 }
00724 
00725 void CPhyloTreePane::x_SendCommand(TCmdID cmd)
00726 {
00727     CEventHandler* target = dynamic_cast<CEventHandler*>(x_GetParent());
00728     if(target)  {
00729         target->OnCommand(cmd);
00730     }
00731 }
00732 
00733 string  CPhyloTreePane::TTHH_NeedTooltip(const wxPoint & pt)
00734 {
00735     return GetCurrRenderer()->TTHH_NeedTooltip(pt);
00736 }
00737 
00738 CTooltipInfo  CPhyloTreePane::TTHH_GetTooltip(const wxRect & rect)
00739 {
00740     return GetCurrRenderer()->TTHH_GetTooltip(rect);
00741 }
00742 
00743 void  CPhyloTreePane::FireCBEvent(void)
00744 {
00745     m_pParent->SendSelChangedEvent();
00746 }
00747 
00748 void  CPhyloTreePane::FireEditEvent(void)
00749 {
00750     m_pParent->SendEditEvent();
00751 }
00752 
00753 TModelUnit  CPhyloTreePane::MMHH_GetScale(EMMScaleType type)
00754 {
00755     const CGlPane& VP = x_GetParent()->GetPort();
00756 
00757     switch(type)    {
00758     case IMinimapHandlerHost::eCurrent:   return VP.GetScaleX();
00759     case IMinimapHandlerHost::eMin: return VP.GetMinScaleX();
00760     case IMinimapHandlerHost::eMax: return VP.GetZoomAllScaleX();
00761     default: _ASSERT(false); return -1;
00762     }
00763 }
00764 
00765 void     CPhyloTreePane::MMHH_EndOp()
00766 {
00767     SaveCurrentView();
00768 }
00769 
00770 
00771 void     CPhyloTreePane::MMHH_Scroll(TModelUnit d_x, TModelUnit d_y)
00772 {
00773     x_GetParent()->Scroll(d_x, d_y);
00774 }
00775 
00776 
00777 TVPUnit  CPhyloTreePane::MMHH_GetVPPosByY(int y) const
00778 {
00779     return GetClientSize().GetHeight() - 1  - y;
00780 }
00781 
00782 
00783 CGlTexture* CPhyloTreePane::MMHH_GetTexture(float& xcoord_limit,
00784                                             float& ycoord_limit)
00785 {
00786     return GetCurrRenderer()->GetTexture(xcoord_limit, ycoord_limit);
00787 }
00788 
00789 
00790 void CPhyloTreePane::HMGH_OnChanged(void)
00791 {
00792     Refresh();
00793     x_GetParent()->SendSelChangedEvent();
00794 }
00795 
00796 void CPhyloTreePane::HMGH_OnRefresh(void)
00797 {
00798     Refresh();
00799 }
00800 
00801 void CPhyloTreePane::OnLeftDown(wxMouseEvent& evt)
00802 {   
00803     SetFocus();
00804     
00805     bool handled = false; 
00806 
00807     if(m_pCurrHandlerRec)  {               
00808         _TRACE("h: " << (void*)dynamic_cast<CMouseZoomHandler*>(m_pCurrHandlerRec->m_pHandler) << " scale Mode: " << m_MouseZoomHandler.IsScaleMode() );
00809 
00810         if (dynamic_cast<CMouseZoomHandler*>(m_pCurrHandlerRec->m_pHandler) != NULL &&
00811             m_MouseZoomHandler.IsScaleMode()) {
00812             handled = x_DispatchEventToHandler(evt, m_pCurrHandlerRec);
00813         }
00814     }    
00815 
00816     if (!handled) {
00817         wxPoint pos = evt.GetPosition();
00818         int area = x_GetAreaByWindowPos(pos);
00819         if( ! x_Handlers_handle(evt, area)) {
00820             evt.Skip();
00821         }
00822     }
00823 
00824     // For some reaon on the mac, and with the phylo_tree drawing (not other views), after
00825     // a dialog is shown or after the window is re-docked, the next left-mouse-down event
00826     // can cause tooltips to disappear.  The way to get the tips back is by doing a hide-show
00827     // pair of calls.  We do this for every left mouse down on mac since we don't know in
00828     // in all cases which ones come after dialog events (and they are not visible to the
00829     // user anyway). The cause of the bug itself is undetermined - perhaps something simiar
00830     // to an activation event which can cause the same problem (on mac)
00831 #if defined(__WXOSX_CARBON__) || defined(__WXMAC_CARBON__)
00832     m_MouseLeftDownEvent = true;
00833 #endif
00834 }
00835 
00836 END_NCBI_SCOPE
Modified on Wed May 23 13:26:26 2012 by modify_doxy.py rev. 337098