|
NCBI C++ ToolKit
|
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
1.7.5.1
Modified on Wed May 23 13:26:26 2012 by modify_doxy.py rev. 337098