src/gui/widgets/aln_crossaln/cross_aln_pane.cpp

Go to the documentation of this file.
00001 /*  $Id: cross_aln_pane.cpp 14858 2007-08-25 16:22:34Z dicuccio $
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:  Vlad Lebedev
00027  *
00028  */
00029 
00030 
00031 #include <ncbi_pch.hpp>
00032 #include "cross_aln_pane.hpp"
00033 
00034 #include <gui/utils/fltk_utils.hpp>
00035 
00036 #include <algorithm>
00037 #include <math.h>
00038 
00039 #include <FL/glut.H>
00040 #include <FL/fl_draw.H>
00041 
00042 
00043 BEGIN_NCBI_SCOPE
00044 
00045 
00046 const TModelUnit kMouseZoomFactor = 25.0;   // per pixel of mouse movement
00047 
00048 
00049 CCrossAlnPane::CCrossAlnPane(int x, int y, int w, int h, const char* label)
00050     : CGlPaneWidgetChild(x, y, w, h, label)
00051 {
00052     m_pCurrHandler = NULL;
00053     m_Renderer.Reset(new CCrossAlnRenderer());
00054 
00055 
00056     m_MouseZoomHandler.SetMode(CMouseZoomHandler::eHorz);
00057     m_MouseZoomHandler.SetHost(static_cast<IMouseZoomHandlerHost*>(this));
00058 
00059     m_SelHandler_Q.SetHost(static_cast<ISelHandlerHost*>(this));
00060     m_SelHandler_S.SetHost(static_cast<ISelHandlerHost*>(this));
00061 
00062     // Now register handlers with their designated areas
00063     x_AddHandler(dynamic_cast<IGlEventHandler*>(&m_MouseZoomHandler), fAllAreas);
00064     x_AddHandler(dynamic_cast<IGlEventHandler*>(&m_SelHandler_Q), fRuler1Area);
00065     x_AddHandler(dynamic_cast<IGlEventHandler*>(&m_SelHandler_S), fRuler2Area);
00066 
00067     // Finally, add self for all unhandled events
00068     x_AddHandler(dynamic_cast<IGlEventHandler*>(this), fAllAreas);
00069 
00070     m_Tooltip.EnableActiveMode(static_cast<ITooltipClient*>(this));
00071     m_Tooltip.SetMode(CTooltip::eHideOnMove);
00072 
00073     m_Event.StandardConfig();
00074 }
00075 
00076 
00077 CCrossAlnPane::~CCrossAlnPane()
00078 {
00079 }
00080 
00081 
00082 // CGlPaneWidgetChild requirements
00083 TVPPoint CCrossAlnPane::GetPortSize(void)
00084 {
00085     return TVPPoint(0,0);
00086 }
00087 
00088 
00089 void CCrossAlnPane::SetDataSource(ICrossAlnDataSource* ds)
00090 {
00091     //TVPRect rc(5, 5, w() - 5, h() - 5);
00092     TVPRect rc(0, 0, w(), h());
00093 
00094     m_SelHandler_Q.ResetSelection(false);
00095     m_SelHandler_S.ResetSelection(false);
00096 
00097     ResetObjectSelection();
00098 
00099     m_Renderer->SetDataSource(rc, ds);
00100     m_DS.Reset(ds);
00101 
00102     Update();
00103 }
00104 
00105 
00106 void CCrossAlnPane::SetWidget(CCrossAlnWidget* pParent)
00107 {
00108     if(m_pParent)   { // disconnect old parent
00109         RemoveListener(m_pParent);
00110     }
00111 
00112     m_pParent = pParent;
00113 
00114     if(m_pParent)   {
00115         AddListener(m_pParent, ePool_Parent);
00116     }
00117 }
00118 
00119 
00120 ICrossAlnDataSource* CCrossAlnPane::GetDataSource()
00121 {
00122     return m_DS;
00123 }
00124 
00125 
00126 void CCrossAlnPane::ColorBySegments()
00127 {
00128     m_Renderer->ColorBySegments();
00129 
00130     redraw();
00131 }
00132 
00133 
00134 void CCrossAlnPane::ColorByScore(CConstRef<CObject_id> score_id)
00135 {
00136     m_Renderer->ColorByScore(score_id);
00137 
00138     redraw();
00139 }
00140 
00141 
00142 CConstRef<CObject_id> CCrossAlnPane::GetScoreId() const
00143 {
00144     return m_Renderer->GetScoreId();
00145 }
00146 
00147 
00148 void CCrossAlnPane::ResetObjectSelection()
00149 {
00150     m_Renderer->ResetObjectSelection();
00151 
00152     redraw();
00153 }
00154 
00155 
00156 void CCrossAlnPane::GetObjectSelection(TConstObjects& objs) const
00157 {
00158     m_Renderer->GetObjectSelection(objs);
00159 }
00160 
00161 
00162 void CCrossAlnPane::SetObjectSelection(const vector<const CSeq_align*> sel_aligns)
00163 {
00164     m_Renderer->SetObjectSelection(sel_aligns);
00165 
00166     redraw();
00167 }
00168 
00169 
00170 
00171 const CCrossAlnPane::TRangeColl& CCrossAlnPane::GetQueryRangeSelection() const
00172 {
00173     return m_SelHandler_Q.GetSelection();
00174 }
00175 
00176 
00177 const CCrossAlnPane::TRangeColl& CCrossAlnPane::GetSubjectRangeSelection() const
00178 {
00179     return m_SelHandler_S.GetSelection();
00180 }
00181 
00182 
00183 void CCrossAlnPane::SetQueryRangeSelection(const TRangeColl& coll)
00184 {
00185     m_SelHandler_Q.SetSelection(coll, true);
00186 }
00187 
00188 
00189 void CCrossAlnPane::SetSubjectRangeSelection(const TRangeColl& coll)
00190 {
00191     m_SelHandler_S.SetSelection(coll, true);
00192 }
00193 
00194 
00195 void CCrossAlnPane::Update()
00196 {
00197     m_Renderer->Update();
00198 
00199     invalidate();
00200     redraw();
00201 }
00202 
00203 
00204 
00205 void CCrossAlnPane::x_AdjustScrollBars(void)
00206 {
00207     CScrollbar* scrollX_Q = (CScrollbar*)(parent()->child(0));
00208     CScrollbar* scrollX_S = (CScrollbar*)(parent()->child(1));
00209 
00210     scrollX_Q->SetListener(NULL);
00211     scrollX_S->SetListener(NULL);
00212 
00213     const TModelRect& rcVQ = m_Renderer->GetRP_Q().GetVisibleRect();
00214     const TModelRect& rcMQ = m_Renderer->GetRP_Q().GetModelLimitsRect();
00215 
00216     const TModelRect& rcVS = m_Renderer->GetRP_S().GetVisibleRect();
00217     const TModelRect& rcMS = m_Renderer->GetRP_S().GetModelLimitsRect();
00218 
00219     TModelUnit page_size_q = min(rcVQ.Right() - rcVQ.Left(), rcMQ.Right());
00220     TModelUnit page_size_s = min(rcVS.Right() - rcVS.Left(), rcMS.Right());
00221 
00222     scrollX_Q->SetRange( int(rcMQ.Left()), int(rcMQ.Right()) );
00223     scrollX_Q->SetPageSize( int(page_size_q) );
00224     scrollX_Q->SetValue( int(rcVQ.Left()) );
00225 
00226     scrollX_Q->SetLineInc( int(m_Renderer->GetScrollLineSize_Q()) );
00227     scrollX_Q->SetPageInc( int(m_Renderer->GetScrollLineSize_Q() * 10) );
00228 
00229     scrollX_S->SetRange( int(rcMS.Left()), int(rcMS.Right()) );
00230     scrollX_S->SetPageSize( int(page_size_s) );
00231     scrollX_S->SetValue( int(rcVS.Left()) );
00232 
00233 
00234     scrollX_S->SetLineInc( int(m_Renderer->GetScrollLineSize_S()) );
00235     scrollX_S->SetPageInc( int(m_Renderer->GetScrollLineSize_S() * 10) );
00236 
00237     scrollX_Q->SetListener(m_pParent);
00238     scrollX_S->SetListener(m_pParent);
00239 }
00240 
00241 
00242 // virtual from CGlPaneWidgetChild
00243 int CCrossAlnPane::x_GetAreaByVPPos(int vp_x, int vp_y)
00244 {
00245     if(m_Renderer->GetRP_Q().GetViewport().PtInRect(vp_x, vp_y)) {
00246         return fRuler1Area;
00247     } else if(m_Renderer->GetRP_S().GetViewport().PtInRect(vp_x, vp_y)) {
00248         return fRuler2Area;
00249     } else {
00250         return fCrossAlign;
00251     }
00252     return fOther;
00253 }
00254 
00255 
00256 int CCrossAlnPane::x_SetAlignAreaByVPPos(int vp_x, int vp_y)
00257 {
00258     TVPRect rc = m_Renderer->GetCP().GetViewport();
00259     TVPUnit hg = rc.Height() / 2;
00260 
00261     // Upper and lower halfs of the pane
00262     TVPRect rcDown = TVPRect( rc.Left(), rc.Bottom(),
00263                               rc.Right(), rc.Top() - hg);
00264     TVPRect rcUp = TVPRect( rc.Left(), rc.Bottom() + hg,
00265                             rc.Right(), rc.Top() );
00266 
00267     if (rcUp.PtInRect(vp_x, vp_y)) {
00268         return fCrossAlignArea2;
00269     }
00270 
00271     if (rcDown.PtInRect(vp_x, vp_y)) {
00272         return fCrossAlignArea1;
00273     }
00274 
00275     return fOther;
00276 }
00277 
00278 
00279 void CCrossAlnPane::x_OnShowPopup()
00280 {
00281     x_GetParent()->OnShowPopup();
00282     //CEvent evt(eShowPopup);
00283     //Send(&evt, eDispatch_Default, ePool_Parent);
00284 }
00285 
00286 
00287 void CCrossAlnPane::x_Render()
00288 {
00289     if (!valid()) {
00290         TVPRect rc(0, 0, w(), h()); //TVPRect rc(5, 5, w() - 5, h() - 5);
00291         m_Renderer->resize(rc);
00292     }
00293 
00294     glClearColor(1, 1, 1, 0);
00295     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00296     if ( !m_DS ) {
00297         return;
00298     }
00299 
00300     m_Renderer->draw();
00301 
00302     glEnable(GL_BLEND);
00303     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00304 
00305     // ZoomHandler indicator
00306     m_MouseZoomHandler.Render(m_Renderer->GetRP_S());
00307     m_MouseZoomHandler.Render(m_Renderer->GetCP());
00308     m_MouseZoomHandler.Render(m_Renderer->GetRP_S());
00309 
00310     // draw linear selection
00311     m_SelHandler_Q.Render(m_Renderer->GetRP_Q());
00312     m_SelHandler_S.Render(m_Renderer->GetRP_S());
00313 
00314     glDisable(GL_BLEND);
00315 
00316     x_AdjustScrollBars();
00317 }
00318 
00319 
00320 
00321 void CCrossAlnPane::x_AddHandler(IGlEventHandler* handler, int area)
00322 {
00323     _ASSERT(handler  &&  area);
00324 
00325     m_lsHandlers.push_back(make_pair(handler, area));
00326 }
00327 
00328 int CCrossAlnPane::handle(CGUIEvent& event, CGlPane& pane)
00329 {
00330     int res = 0;
00331     switch(event.GetFLTKEvent())   {
00332     case FL_PUSH:    res =  x_OnMousePush(event); break;
00333     case FL_DRAG:    res =  x_OnMouseDrag(event); break;
00334     case FL_RELEASE: res =  x_OnMouseRelease(event); break;
00335     case FL_MOVE:    res =  x_OnMouseMove(); break;
00336     case FL_KEYDOWN: res =  x_OnKeyDown(event); break;
00337     case FL_KEYUP:   res =  x_OnKeyUp(); break;
00338     }
00339 
00340     m_Tooltip.Handle(event.GetFLTKEvent());
00341     return res;
00342 }
00343 
00344 
00345 ////////////////////////////////////////////////////////////////////////////////
00346 /// event handlers
00347 int CCrossAlnPane::x_OnKeyDown(CGUIEvent& event)
00348 {
00349     return 0;
00350 }
00351 
00352 int CCrossAlnPane::x_OnKeyUp(void)
00353 {
00354     return 0;
00355 }
00356 
00357 int CCrossAlnPane::x_OnMousePush(CGUIEvent& event)
00358 {
00359     CGUIEvent::EGUIState  state  = event.GetGUIState();
00360 
00361     if ((state == CGUIEvent::eSelectState  ||  state == CGUIEvent::eSelectIncState)
00362         && event.GetGUISignal() == CGUIEvent::eSelectSignal)
00363     {
00364         int x = Fl::event_x();
00365         int y = h() - Fl::event_y();
00366 
00367         m_PushArea = static_cast<EHandlerArea>(x_GetAreaByWindowPos(
00368                         Fl::event_x(), Fl::event_y()));
00369 
00370         m_CrossAlnHalf = static_cast<EHandlerArea>(x_SetAlignAreaByVPPos(
00371                         Fl::event_x(), Fl::event_y()));
00372 
00373         if (m_PushArea == fCrossAlign) {
00374             TRangeColl coll_q = m_SelHandler_Q.GetSelection();
00375             TRangeColl coll_s = m_SelHandler_S.GetSelection();
00376             // Distinguish selection and incremental selection
00377             if (state == CGUIEvent::eSelectState) {
00378                 ResetObjectSelection();
00379                 coll_q.clear();
00380                 coll_s.clear();
00381             }
00382 
00383             // double click zooms on the feature/alignment/etc
00384             if (Fl::event_clicks()) {
00385                 TModelRect rc = m_Renderer->HitTest(x, y);
00386                 //ZoomOnRect(rc);
00387                 SquareOnRect(rc);
00388             } else {
00389                 TModelRect rc = m_Renderer->SelectHitTest(x, y);
00390 
00391                 coll_q.CombineWith(TSeqRange(TSeqPos(rc.Left()),
00392                                    TSeqPos(rc.Right()-1)));
00393                 coll_s.CombineWith(TSeqRange(TSeqPos(rc.Bottom()),
00394                                              TSeqPos(rc.Top()-1)));
00395 
00396                 m_SelHandler_Q.SetSelection(coll_q, true);
00397                 m_SelHandler_S.SetSelection(coll_s, true);
00398 
00399                 // broadcast selection change
00400                 CEvent evt(CEvent::eEvent_Message, CViewEvent::eWidgetSelectionChanged);
00401                 Send(&evt, CEventHandler::eDispatch_Default,
00402                                 CEventHandler::ePool_Parent);
00403             }
00404 
00405             redraw();
00406             return 1;
00407         } // ignore rulers
00408     } // selection events only
00409     return 0;
00410 }
00411 
00412 int CCrossAlnPane::x_OnMouseMove(void)
00413 {
00414     return 0;
00415 }
00416 
00417 int CCrossAlnPane::x_OnMouseDrag(CGUIEvent& event)
00418 {
00419     return 1; // always handle drags
00420 }
00421 
00422 int CCrossAlnPane::x_OnMouseRelease(CGUIEvent& event)
00423 {
00424     return 0;
00425 }
00426 
00427 
00428 // event handling starts here
00429 int CCrossAlnPane::handle(int event)
00430 {
00431     if(event == FL_KEYDOWN  &&  Fl::event_key() == FL_Tab)  {
00432         return 0; // ignore
00433     }
00434     m_Event.OnFLTKEvent(event);
00435 
00436     int res = 0;
00437     switch(event)   {
00438     case FL_FOCUS:
00439     case FL_UNFOCUS:    redraw(); return 1;
00440     case FL_KEYDOWN:
00441     case FL_KEYUP:      res = x_HandleKeyEvent();     break;
00442     case FL_MOVE:       res = x_HandleMouseMove();    break;
00443     case FL_PUSH:       res = x_HandleMousePush();    break;
00444     case FL_DRAG:       res = x_HandleMouseDrag();    break;
00445     case FL_RELEASE:    res = x_HandleMouseRelease(); break;
00446     case FL_MOUSEWHEEL: res = x_HandleMouseWheel();   break;
00447     default:            res = CGlCanvas::handle(event);
00448     }
00449 
00450     return res;
00451 }
00452 
00453 
00454 int CCrossAlnPane::x_HandleKeyEvent()
00455 {
00456     IGlEventHandler* pH = NULL; //dummy
00457     m_PushArea = static_cast<EHandlerArea>(x_GetAreaByWindowPos(
00458                         Fl::event_x(), Fl::event_y()));
00459 
00460     int res = x_Handlers_handle(m_PushArea, pH, false);
00461 
00462     if (res == 0  &&  m_Event.GetFLTKEvent() == FL_KEYDOWN) {
00463         switch(m_Event.GetGUISignal()) {
00464         case CGUIEvent::eZoomInSignal:  ZoomIn(); break;
00465         case CGUIEvent::eZoomOutSignal: ZoomOut(); break;
00466         case CGUIEvent::eZoomAllSignal: ZoomAll(); break;
00467         default: break;
00468         }
00469     }
00470 
00471     return res;
00472 }
00473 
00474 
00475 int CCrossAlnPane::x_HandleMouseMove()
00476 {
00477     int res = 0;
00478     IGlEventHandler* pH = NULL; //dummy
00479 
00480     m_PushArea = static_cast<EHandlerArea>(x_GetAreaByWindowPos(
00481                         Fl::event_x(), Fl::event_y()));
00482     res = x_Handlers_handle(m_PushArea, pH);
00483 
00484     if(res == 0)    {
00485         fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);
00486     }
00487 
00488     m_pCurrHandler = NULL;
00489     return res;
00490 }
00491 
00492 
00493 
00494 int CCrossAlnPane::x_HandleMousePush()
00495 {
00496     if(Fl::focus() != static_cast<Fl_Widget*>(this))    {
00497         take_focus();
00498         m_Event.OnFLTKEvent(FL_PUSH); // restore event state after focus handling
00499     }
00500 
00501     int res = 0;
00502     if(m_Event.GetGUISignal() == CGUIEvent::ePopupSignal)   {
00503         x_OnShowPopup();
00504         res = 1;
00505     } else {
00506         IGlEventHandler* pH = NULL; //dummy
00507 
00508         m_PushArea = static_cast<EHandlerArea>(x_GetAreaByWindowPos(
00509                         Fl::event_x(), Fl::event_y()));
00510 
00511         m_CrossAlnHalf = static_cast<EHandlerArea>(x_SetAlignAreaByVPPos(
00512                         Fl::event_x(), Fl::event_y()));
00513 
00514         res = x_Handlers_handle(m_PushArea, pH, true);
00515 
00516         m_pCurrHandler = pH;
00517     }
00518     if(res == 0)    {
00519         fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);
00520     }
00521     return res;
00522 }
00523 
00524 
00525 int CCrossAlnPane::x_HandleMouseDrag()
00526 {
00527     int res = 0;
00528     if(m_pCurrHandler)  {
00529         res = m_pCurrHandler->handle(m_Event, m_CurrPane);
00530     }
00531     if(res ==0) {
00532         fl_cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);
00533     }
00534     return res;
00535 }
00536 
00537 
00538 int CCrossAlnPane::x_HandleMouseRelease()
00539 {
00540     if(m_Event.GetGUISignal() == CGUIEvent::ePopupSignal)   {
00541         x_OnShowPopup();
00542         return 1;
00543     } else return x_HandleMouseDrag();
00544 }
00545 
00546 
00547 int CCrossAlnPane::x_HandleMouseWheel()
00548 {
00549     IGlEventHandler* pH = NULL; //dummy
00550     int res = x_Handlers_handle(fAllAreas, pH, false);
00551     if(! res)   {
00552         int d_x = Fl::event_dx();
00553         Scroll((TModelUnit) d_x, 0);
00554     }
00555     return res;
00556 }
00557 
00558 
00559 int CCrossAlnPane::x_Handlers_handle(int area,
00560                     IGlEventHandler*& handler, bool ignore_curr)
00561 {
00562     int res = 0;
00563 
00564     switch (area) {
00565     case fRuler1Area:
00566         m_CurrPane = m_Renderer->GetRP_Q();
00567         break;
00568     case fRuler2Area:
00569         m_CurrPane = m_Renderer->GetRP_S();
00570         break;
00571     case fCrossAlign:
00572         if (m_CrossAlnHalf == fCrossAlignArea1)
00573                 m_CurrPane = m_Renderer->GetRP_Q();
00574         if (m_CrossAlnHalf == fCrossAlignArea2)
00575                 m_CurrPane = m_Renderer->GetRP_S();
00576         break;
00577     case fAllAreas:
00578     default:
00579         m_CurrPane = m_Renderer->GetCP();
00580     }
00581 
00582 
00583     IGlEventHandler* pFirst = ignore_curr ? NULL : m_pCurrHandler;
00584     if (pFirst)  {
00585         handler = m_pCurrHandler;
00586         res = m_pCurrHandler->handle(m_Event, m_CurrPane);
00587     }
00588 
00589     if (res == 0)    { // not handles by pFirst - iterate through over handlers
00590         NON_CONST_ITERATE(THandlerList, it, m_lsHandlers) {
00591             handler = it->first;
00592             if ( (it->second & area)  &&  (handler != pFirst) )    {
00593                 res = handler->handle(m_Event, m_CurrPane);
00594                 if (res) break;
00595             }
00596         }
00597     }
00598     if (res == 0)    handler = NULL;
00599     return res;
00600 }
00601 
00602 
00603 
00604 
00605 // IMouseZoomHandlerHost implementation
00606 TModelUnit CCrossAlnPane::MZHH_GetScale(EScaleType type)
00607 {
00608     m_CrossAlnHalf = static_cast<EHandlerArea>(x_SetAlignAreaByVPPos(
00609                         Fl::event_x(), Fl::event_y()));
00610 
00611     if (m_CrossAlnHalf == fCrossAlignArea1) {
00612         switch(type) {
00613         case eCurrent: return m_Renderer->GetRP_Q().GetScaleX();
00614         case eMin:     return m_Renderer->GetRP_Q().GetMinScaleX();
00615         case eMax:     return m_Renderer->GetRP_Q().GetZoomAllScaleX();
00616         default: _ASSERT(false); return -1;
00617         }
00618     } else {
00619         switch(type) {
00620         case eCurrent: return m_Renderer->GetRP_S().GetScaleX();
00621         case eMin:     return m_Renderer->GetRP_S().GetMinScaleX();
00622         case eMax:     return m_Renderer->GetRP_S().GetZoomAllScaleX();
00623         default: _ASSERT(false); return -1;
00624         }
00625     }
00626 }
00627 
00628 
00629 void CCrossAlnPane::MZHH_SetScale(TModelUnit scale, const TModelPoint& point)
00630 {
00631     TModelUnit scale_y_q = m_Renderer->GetRP_Q().GetScaleY();
00632     TModelUnit scale_y_s = m_Renderer->GetRP_S().GetScaleY();
00633 
00634     if (!Fl::event_shift()) {
00635         TModelUnit sc_x1 = m_Renderer->GetRP_Q().GetScaleX();
00636         TModelUnit sc_x2 = m_Renderer->GetRP_S().GetScaleX();
00637 
00638         TModelUnit scale1, scale2;
00639         TModelPoint point1, point2;
00640         if (m_CrossAlnHalf == fCrossAlignArea1) {
00641             scale1 = scale;
00642             point1 = point;
00643             scale2 = scale1 * sc_x2 / sc_x1;
00644 
00645             // Re-project point from one pane to another
00646             TVPUnit tmp_vp = m_Renderer->GetRP_Q().ProjectX( point.X() );
00647             TModelUnit tmp_mu = m_Renderer->GetRP_S().UnProjectX( tmp_vp );
00648             point2 = TModelPoint(tmp_mu, point.Y());
00649         } else {
00650             scale2 = scale;
00651             scale1 = scale2 * sc_x1 / sc_x2;
00652             point2 = point;
00653 
00654             // Re-project point from one pane to another
00655             TVPUnit tmp_vp = m_Renderer->GetRP_S().ProjectX( point.X() );
00656             TModelUnit tmp_mu = m_Renderer->GetRP_Q().UnProjectX( tmp_vp );
00657             point1 = TModelPoint(tmp_mu, point.Y());
00658         }
00659 
00660         m_Renderer->SetScaleRef_Q(scale1, scale_y_q, point1);
00661         m_Renderer->SetScaleRef_S(scale2, scale_y_s, point2);
00662 
00663     } else {
00664         if (m_CrossAlnHalf == fCrossAlignArea1)
00665             m_Renderer->SetScaleRef_Q(scale, scale_y_q, point);
00666         else
00667             m_Renderer->SetScaleRef_S(scale, scale_y_s, point);
00668     }
00669 
00670     NotifyVisibleRangeChanged();
00671 }
00672 
00673 
00674 void CCrossAlnPane::MZHH_ZoomRect(const TModelRect& rect)
00675 {
00676     TModelUnit l1, l2, r1, r2;
00677     if (m_CrossAlnHalf == fCrossAlignArea1) {
00678         l1 = rect.Left();
00679         r1 = rect.Right();
00680 
00681         TVPUnit lv1 = m_Renderer->GetRP_Q().ProjectX(l1);
00682         TVPUnit rv1 = m_Renderer->GetRP_Q().ProjectX(r1);
00683 
00684         l2 = m_Renderer->GetRP_S().UnProjectX(lv1);
00685         r2 = m_Renderer->GetRP_S().UnProjectX(rv1);
00686     } else {
00687         l2 = rect.Left();
00688         r2 = rect.Right();
00689 
00690         TVPUnit lv2 = m_Renderer->GetRP_S().ProjectX(l2);
00691         TVPUnit rv2 = m_Renderer->GetRP_S().ProjectX(r2);
00692 
00693         l1 = m_Renderer->GetRP_Q().UnProjectX(lv2);
00694         r1 = m_Renderer->GetRP_Q().UnProjectX(rv2);
00695     }
00696 
00697     ZoomOnRange_Q(l1, r1);
00698     ZoomOnRange_S(l2, r2);
00699 
00700     // translate the notification to the standard message
00701     NotifyVisibleRangeChanged();
00702 }
00703 
00704 
00705 void CCrossAlnPane::MZHH_ZoomPoint(const TModelPoint& point, TModelUnit factor)
00706 {
00707     ERR_POST("CCrossAlnPane::MZHH_ZoomPoint() not implemented!");
00708     NotifyVisibleRangeChanged();
00709 }
00710 
00711 void CCrossAlnPane::MZHH_Scroll(TModelUnit d_x, TModelUnit d_y)
00712 {
00713     const TModelRect& rc_q = m_Renderer->GetRP_Q().GetVisibleRect();
00714     const TModelRect& rc_s = m_Renderer->GetRP_S().GetVisibleRect();
00715 
00716     // the d_x here are in cross alignment pane model
00717     // space (which set to be 0 to 1). We need to recalculate to
00718     // proper values of ruler panes.
00719     if (!Fl::event_shift()) {
00720         TModelUnit dx_q, dx_s;
00721         if (m_CrossAlnHalf == fCrossAlignArea1) {
00722             dx_q = d_x;
00723             dx_s = dx_q * rc_s.Width() / rc_q.Width();
00724         } else {
00725             dx_s = d_x;
00726             dx_q = dx_s * rc_q.Width() / rc_s.Width();
00727         }
00728         Scroll(rc_q.Left() + dx_q, rc_s.Left() + dx_s);
00729     } else {
00730         if (m_CrossAlnHalf == fCrossAlignArea1) {
00731             Scroll(rc_q.Left() + d_x, rc_s.Left());
00732         } else {
00733             Scroll(rc_q.Left(), rc_s.Left() + d_x);
00734         }
00735     }
00736 
00737     // translate the notification to the standard message
00738     NotifyVisibleRangeChanged();
00739 }
00740 
00741 
00742 TVPUnit CCrossAlnPane::MZHH_GetVPPosByY(int y) const
00743 {
00744     return h() - 1  - y;
00745 }
00746 
00747 
00748 void CCrossAlnPane::MZHH_Redraw(void)
00749 {
00750     redraw();
00751 }
00752 
00753 
00754 void CCrossAlnPane::MZHH_EndOp()
00755 {
00756     // translate the notification to the standard message
00757     NotifyVisibleRangeChanged();
00758 }
00759 // IMouseZoomHandlerHost end
00760 
00761 
00762 
00763 // ISelHandlerHost
00764 TModelUnit CCrossAlnPane::SHH_GetModelByWindow(int z, EOrientation orient)
00765 {
00766     if (m_PushArea == fRuler1Area) {
00767         switch(orient)  {
00768         case eHorz: return m_Renderer->GetRP_Q().UnProjectX(z);
00769         case eVert: return m_Renderer->GetRP_Q().UnProjectY(h() - z);
00770         default:    _ASSERT(false); return -1;
00771         }
00772     } else {
00773         switch(orient)  {
00774         case eHorz: return m_Renderer->GetRP_S().UnProjectX(z);
00775         case eVert: return m_Renderer->GetRP_S().UnProjectY(h() - z);
00776         default:    _ASSERT(false); return -1;
00777         }
00778     }
00779 }
00780 
00781 TVPUnit CCrossAlnPane::SHH_GetWindowByModel(TModelUnit z, EOrientation orient)
00782 {
00783     if (m_PushArea == fRuler1Area) {
00784         switch(orient)  {
00785         case eHorz: return m_Renderer->GetRP_Q().ProjectX(z);
00786         case eVert: return h() - m_Renderer->GetRP_Q().ProjectY(z);
00787         default:    _ASSERT(false); return -1;
00788         }
00789     } else {
00790         switch(orient)  {
00791         case eHorz: return m_Renderer->GetRP_S().ProjectX(z);
00792         case eVert: return h() - m_Renderer->GetRP_S().ProjectY(z);
00793         default:    _ASSERT(false); return -1;
00794         }
00795     }
00796 }
00797 
00798 
00799 void CCrossAlnPane::SHH_Redraw()
00800 {
00801     redraw();
00802 }
00803 
00804 
00805 void CCrossAlnPane::SHH_OnChanged()
00806 {
00807     if (!GetQueryRangeSelection().size()  ||
00808         !GetSubjectRangeSelection().size())
00809     {
00810         ResetObjectSelection();
00811     }
00812 
00813     redraw();
00814     // broadcast
00815     CEvent evt(CEvent::eEvent_Message, CViewEvent::eWidgetSelectionChanged);
00816     Send(&evt, CEventHandler::eDispatch_Default,
00817                               CEventHandler::ePool_Parent);
00818 }
00819 // ISelHandlerHost end
00820 
00821 
00822 ///////////////////////////////////////////////////////////////////////////////
00823 /// ITooltip Implementation
00824 bool CCrossAlnPane::TC_NeedTooltip(int x, int y)
00825 {
00826     m_Renderer->GetTooltip(x, h() - y, &m_TooltipText);
00827     return m_TooltipText.length() > 0;
00828 }
00829 
00830 
00831 string CCrossAlnPane::TC_GetTooltip(int& x, int& y, int& w, int& h)
00832 {
00833     return m_TooltipText;
00834 }
00835 
00836 // ITooltip end
00837 
00838 // --- Scrolling --------------------------------------------------
00839 void CCrossAlnPane::Scroll(TModelUnit x1, TModelUnit x2)
00840 {
00841     // "lock" both scrollbars if Shift key is pressed. That will scroll all panels
00842     // together (withing each panel limits)
00843     if (!Fl::event_shift()) {
00844         const TModelRect& rc1 = m_Renderer->GetRP_Q().GetVisibleRect();
00845         const TModelRect& rc2 = m_Renderer->GetRP_S().GetVisibleRect();
00846 
00847         // Find the scroll "delta"
00848         int dX1 = int(x1 - rc1.Left());
00849         int dX2 = int(x2 - rc2.Left());
00850 
00851         if (dX1 != 0) x2 = x2 + dX1;
00852         if (dX2 != 0) x1 = x1 + dX2;
00853     }
00854 
00855     m_Renderer->Scroll(x1, x2);
00856     redraw();
00857 }
00858 
00859 
00860 void CCrossAlnPane::SquareOnRect(TModelRect rc)
00861 {
00862     if (rc.Width() == 0 || rc.Height() == 0) return;
00863 
00864     m_Renderer->SquareOnRect(rc);
00865 
00866     NotifyVisibleRangeChanged();
00867 }
00868 
00869 
00870 void CCrossAlnPane::ZoomOnRect(TModelRect rc)
00871 {
00872     if (rc.Width() == 0 || rc.Height() == 0) return;
00873 
00874     ZoomOnRange_Q( rc.Left(), rc.Right() );
00875     ZoomOnRange_S( rc.Bottom(), rc.Top() );
00876 
00877     NotifyVisibleRangeChanged();
00878 }
00879 
00880 
00881 void CCrossAlnPane::ZoomOnRange_Q(TModelUnit from, TModelUnit to)
00882 {
00883     m_Renderer->ZoomOnRange_Q(from, to);
00884     NotifyVisibleRangeChanged();
00885 }
00886 
00887 void CCrossAlnPane::ZoomOnRange_S(TModelUnit from, TModelUnit to)
00888 {
00889     m_Renderer->ZoomOnRange_S(from, to);
00890     NotifyVisibleRangeChanged();
00891 }
00892 
00893 
00894 void CCrossAlnPane::ZoomIn_Q()
00895 {
00896     m_Renderer->ZoomIn_Q();
00897     NotifyVisibleRangeChanged();
00898 }
00899 
00900 
00901 void CCrossAlnPane::ZoomOut_Q()
00902 {
00903     m_Renderer->ZoomOut_Q();
00904     NotifyVisibleRangeChanged();
00905 }
00906 
00907 void CCrossAlnPane::ZoomAll(void)
00908 {
00909     ZoomAll_Q();
00910     ZoomAll_S();
00911 }
00912 
00913 
00914 void CCrossAlnPane::ZoomIn(void)
00915 {
00916     ZoomIn_Q();
00917     ZoomIn_S();
00918 }
00919 
00920 void CCrossAlnPane::ZoomOut(void)
00921 {
00922     ZoomOut_Q();
00923     ZoomOut_S();
00924 }
00925 
00926 
00927 void CCrossAlnPane::ZoomAll_Q(void)
00928 {
00929     m_Renderer->ZoomAll_Q();
00930     NotifyVisibleRangeChanged();
00931 }
00932 
00933 void CCrossAlnPane::ZoomToSeq_Q(void)
00934 {
00935     m_Renderer->ZoomToSeq_Q();
00936     NotifyVisibleRangeChanged();
00937 }
00938 
00939 
00940 // Subject
00941 void CCrossAlnPane::ZoomIn_S()
00942 {
00943     m_Renderer->ZoomIn_S();
00944     NotifyVisibleRangeChanged();
00945 }
00946 
00947 
00948 void CCrossAlnPane::ZoomOut_S()
00949 {
00950     m_Renderer->ZoomOut_S();
00951     NotifyVisibleRangeChanged();
00952 }
00953 
00954 
00955 void CCrossAlnPane::ZoomAll_S(void)
00956 {
00957     m_Renderer->ZoomAll_S();
00958     NotifyVisibleRangeChanged();
00959 }
00960 
00961 void CCrossAlnPane::ZoomToSeq_S(void)
00962 {
00963     m_Renderer->ZoomToSeq_S();
00964     NotifyVisibleRangeChanged();
00965 }
00966 
00967 
00968 void CCrossAlnPane::NotifyVisibleRangeChanged()
00969 {
00970     CEvent evt(CEvent::eEvent_Message, CViewEvent::eWidgetRangeChanged);
00971     Send(&evt, CEventHandler::eDispatch_Default,
00972                     CEventHandler::ePool_Parent);
00973     redraw();
00974 }
00975 
00976 
00977 END_NCBI_SCOPE
00978 
00979 

Generated on Sun Feb 8 21:57:00 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Mon Feb 09 14:47:14 2009 by modify_doxy.py rev. 117643