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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: glpane.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 20:50:55  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.11
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: glpane.cpp,v 1000.3 2004/06/01 20:50:55 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:  Andrey Yazhuk
  35.  *
  36.  * File Description:
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <gui/opengl/glpane.hpp>
  41. #include <gui/opengl/glutils.hpp>
  42. #include <math.h>
  43. BEGIN_NCBI_SCOPE
  44. ///////////////////////////////////////////////////////////////////////////////
  45. /// CGlPane
  46. CGlPane::CGlPane(EProjMatrixPolicy policy)
  47. : m_prcClip(NULL),
  48.   m_Mode(eNone),
  49.   m_MatrixPolicy(policy),
  50.   m_AdjustX(fAdjustAll),
  51.   m_AdjustY(fAdjustAll),
  52.   m_bEnableOffset(false),
  53.   m_bZoomEnX(true),
  54.   m_bZoomEnY(true),
  55.   m_ZoomFactor(2.0),
  56.   m_bProportionalMode(false),
  57.   m_TypeX(eOriginLeft), m_TypeY(eOriginBottom),
  58.   m_MinScaleX(0), m_MinScaleY(0)
  59. {
  60. }
  61. CGlPane::~CGlPane()
  62. {
  63.    // _ASSERT(m_Mode == eNone); // should be closed first
  64. }
  65. void    CGlPane::SetViewport(const TVPRect& r)
  66. {
  67.     m_rcVP = r;
  68.     
  69.     // applying constraints
  70.     x_CorrectScale(m_rcOrigVisible.CenterPoint());
  71.     x_ScaleToFitLimits();
  72.     x_ShiftToFitLimits();
  73.     x_AdjustVisibleRect();
  74. }
  75. void    CGlPane::SetVisibleRect(const TModelRect& r)
  76. {
  77.     m_rcVisible = m_rcOrigVisible = r;
  78. }
  79. TModelUnit  CGlPane::GetScaleX(void) const
  80. {
  81.     return m_rcVisible.Width() / m_rcVP.Width();
  82. }
  83. TModelUnit  CGlPane::GetScaleY(void) const
  84. {
  85.     return m_rcVisible.Height() / m_rcVP.Height();
  86. }
  87. TModelUnit    CGlPane::GetZoomAllScaleX(void) const
  88. {
  89.     return m_rcLimits.Width() / m_rcVP.Width();
  90. }
  91. TModelUnit    CGlPane::GetZoomAllScaleY(void) const
  92. {
  93.     return m_rcLimits.Height() / m_rcVP.Height();
  94. }
  95. inline void    CGlPane::x_AssertNotOpen(void) const
  96. {
  97.     _ASSERT(GetProjMode() == eNone);
  98. }
  99. inline void    CGlPane::x_AssertOrtho(void) const
  100. {
  101.     _ASSERT(GetProjMode() == eOrtho);
  102. }
  103.            
  104. bool    CGlPane::Open(EProjectionMode mode)
  105. {    
  106.     _ASSERT(mode != eNone);
  107.     _ASSERT(m_Mode == eNone); //should not be already open 
  108.     bool ok = false;
  109.     if (mode != m_Mode) {
  110.         switch (mode) {
  111.         case eOrtho: {
  112.             ok = x_OpenOrtho();
  113.             break;
  114.         }
  115.         case ePixels: {
  116.             ok = x_OpenPixels();
  117.             break;
  118.         }
  119.         default: _ASSERT(false); //other modes are unsupported
  120.         } //switch
  121.     } 
  122.     if (ok) {
  123.         m_Mode = mode;
  124.     }
  125.     return ok;
  126. }
  127. void    CGlPane::Close(void)
  128. {
  129.     _ASSERT(m_Mode != eNone); // should be open
  130.     if(m_Mode != eNone)
  131.     {
  132.         glMatrixMode(GL_PROJECTION);
  133.         //glPopMatrix();
  134.         glDisable(GL_SCISSOR_TEST);
  135.         m_Mode = eNone;
  136.     }
  137. }
  138. inline void    CGlPane::x_Open_SetViewport()
  139. {
  140.     _ASSERT(m_rcVP.Width()  &&  m_rcVP.Height());
  141.     
  142.     glViewport(m_rcVP.Left(), m_rcVP.Bottom(), m_rcVP.Width(), m_rcVP.Height());
  143.     // setup clipping
  144.     glEnable(GL_SCISSOR_TEST);
  145.     TVPRect rc_cl(m_rcVP);
  146.     if(m_prcClip) { //additional clip rect has been provided
  147.         rc_cl.IntersectWith(*m_prcClip);
  148.     }
  149.     glScissor(rc_cl.Left(), rc_cl.Bottom(), rc_cl.Width(), rc_cl.Height());
  150. }
  151. bool    CGlPane::x_OpenOrtho()
  152. {
  153.     x_Open_SetViewport();
  154.     glMatrixMode(GL_PROJECTION);
  155.     //glPushMatrix();
  156.     glLoadIdentity();
  157.     TModelUnit half_pix_w = m_rcVisible.Width() / (2 * m_rcVP.Width());
  158.     TModelUnit half_pix_h = m_rcVisible.Height() / (2 * m_rcVP.Height());
  159.     
  160.     TModelUnit left, right, top, bottom;
  161.     if(m_bEnableOffset) {
  162.         left = bottom = 0.0;
  163.         right = m_rcVisible.Width();
  164.         top = m_rcVisible.Height();
  165.     } else {
  166.         left = m_rcVisible.Left();
  167.         right = m_rcVisible.Right();
  168.         bottom = m_rcVisible.Bottom();
  169.         top = m_rcVisible.Top();
  170.     }
  171.     gluOrtho2D( left - half_pix_w, right + half_pix_w, 
  172.                 bottom - half_pix_h, top + half_pix_h);
  173.             
  174.     glMatrixMode(GL_MODELVIEW);
  175.     switch(m_MatrixPolicy)  {
  176.     case eNeverUpdate: break;
  177.     case eAlwaysUpdate:  x_UpdateProjectMatrices(); break;
  178.     }
  179.         
  180.     return true;
  181. }
  182. bool    CGlPane::x_OpenPixels()
  183. {
  184.     x_Open_SetViewport();
  185.         
  186.     glMatrixMode(GL_PROJECTION);
  187.     //glPushMatrix();
  188.     glLoadIdentity();
  189.     glOrtho(m_rcVP.Left() - 0.5, m_rcVP.Right() + 0.5, m_rcVP.Bottom() - 0.5, m_rcVP.Top() + 0.5,
  190.             -1, 1);
  191.     glMatrixMode(GL_MODELVIEW);
  192.     return true;
  193. }
  194. void    CGlPane::x_UpdateProjectMatrices(void)
  195. {
  196.     glGetIntegerv(GL_VIEWPORT, m_mxVP);
  197.     glGetDoublev(GL_PROJECTION_MATRIX, m_mxProjection);
  198.     glGetDoublev(GL_MODELVIEW_MATRIX, m_mxModelView);
  199. }
  200. ////////////////////////////////////////////////////////////////////////////////
  201. // Zoom fucntions
  202. bool    CGlPane::IsZoomInAvaiable()
  203. {        
  204.     return m_bZoomEnX || m_bZoomEnY;
  205. }
  206. bool    CGlPane::IsZoomOutAvaiable(void)
  207. {
  208.     bool    av_x = ::fabs(m_rcVisible.Right() - m_rcVisible.Left()) 
  209.                     < ::fabs(m_rcLimits.Right() - m_rcLimits.Left());    
  210.     bool    av_y = ::fabs(m_rcVisible.Top() - m_rcVisible.Bottom()) 
  211.                     < ::fabs(m_rcLimits.Top() - m_rcLimits.Bottom());    
  212.     return (m_bZoomEnX && av_x) || (m_bZoomEnY && av_y);
  213. }
  214. void    CGlPane::ZoomAll(int options)
  215. {
  216.     if((options & fZoomX)  && (m_bZoomEnX  ||  (options & fForce)))  {
  217.         m_rcVisible.SetLeft(m_rcLimits.Left());
  218.         m_rcVisible.SetRight(m_rcLimits.Right());
  219.         
  220.         m_rcOrigVisible.SetLeft(m_rcLimits.Left());    
  221.         m_rcOrigVisible.SetRight(m_rcLimits.Right());
  222.     }
  223.     if((options & fZoomY)  && (m_bZoomEnY  ||  (options & fForce)))  {
  224.         m_rcVisible.SetBottom(m_rcLimits.Bottom());
  225.         m_rcVisible.SetTop(m_rcLimits.Top());
  226.         
  227.         m_rcOrigVisible.SetBottom(m_rcLimits.Bottom());    
  228.         m_rcOrigVisible.SetTop(m_rcLimits.Top());
  229.     }
  230.     // applying constraints
  231.     x_CorrectScale(m_rcOrigVisible.CenterPoint());
  232.     x_AdjustVisibleRect();
  233. }
  234. void    CGlPane::ZoomPoint(TModelUnit x, TModelUnit y, TModelUnit factor, int options)
  235. {
  236.     _ASSERT(factor > 0.01  && factor < 100); // keep it reasonable
  237.     m_rcOrigVisible = m_rcVisible;
  238.     if ((options & fZoomX)  &&  m_bZoomEnX) {
  239.         TModelUnit new_w = m_rcVisible.Width() / factor;
  240.         TModelUnit left = x - new_w / 2;
  241.         m_rcOrigVisible.SetLeft(left);
  242.         m_rcOrigVisible.SetRight(left + new_w);
  243.     }
  244.     if ((options & fZoomY)  &&  m_bZoomEnY) {
  245.         TModelUnit new_h = m_rcVisible.Height() / factor;
  246.         TModelUnit bottom = y - new_h / 2;
  247.         m_rcOrigVisible.SetBottom(bottom);
  248.         m_rcOrigVisible.SetTop(bottom + new_h);
  249.     }    
  250.     m_rcVisible = m_rcOrigVisible;    
  251.     
  252.     // applying constraints
  253.     x_CorrectScale(m_rcOrigVisible.CenterPoint());
  254.     x_ScaleToFitLimits();
  255.     x_ShiftToFitLimits();
  256.     x_AdjustVisibleRect();
  257. }
  258. void    CGlPane::ZoomInCenter(int options)
  259. {
  260.     ZoomIn(m_rcVisible.CenterPoint(), options);
  261. }
  262. void    CGlPane::ZoomOutCenter(int options)
  263. {
  264.     ZoomOut(m_rcVisible.CenterPoint(), options);
  265. }
  266. void    CGlPane::ZoomRect(const TModelRect& r)
  267. {
  268.     SetVisibleRect(r);
  269.     TModelPoint p_center = m_rcVisible.CenterPoint();
  270.     
  271.     x_CorrectScale(p_center);
  272.     x_ScaleToFitLimits(); //### merege with CorrectScale
  273.     x_ShiftToFitLimits();
  274.     x_AdjustVisibleRect();
  275. }
  276. void    CGlPane::SetScale(TModelUnit scale_x, TModelUnit scale_y, TModelPoint p_center)
  277. {
  278.     TModelUnit new_w = ::abs(m_rcVP.Width()) * scale_x;
  279.     TModelUnit left = p_center.X() - new_w / 2;
  280.     m_rcOrigVisible.SetLeft(left);
  281.     m_rcOrigVisible.SetRight(left + new_w);
  282.     
  283.     TModelUnit new_h = ::abs(m_rcVP.Height()) * scale_y;
  284.     TModelUnit bottom = p_center.Y() - new_h / 2;
  285.     m_rcOrigVisible.SetBottom(bottom);
  286.     m_rcOrigVisible.SetTop(bottom + new_h); 
  287.     m_rcVisible = m_rcOrigVisible;
  288.     x_CorrectScale(p_center);
  289.     x_ScaleToFitLimits(); 
  290.     x_ShiftToFitLimits();
  291.     x_AdjustVisibleRect();
  292. }
  293. void    CGlPane::SetScaleRefPoint(TModelUnit scale_x, TModelUnit scale_y,
  294.                              TModelPoint p_ref)
  295. {
  296.     TModelUnit new_w = ::abs(m_rcVP.Width()) * scale_x;    
  297.     TModelUnit left_ratio = (p_ref.X() - m_rcVisible.Left()) / m_rcVisible.Width();
  298.     TModelUnit left = p_ref.X() - new_w * left_ratio;
  299.     m_rcOrigVisible.SetLeft(left);
  300.     m_rcOrigVisible.SetRight(left + new_w);
  301.     TModelUnit new_h = ::abs(m_rcVP.Height()) * scale_y;
  302.     TModelUnit bottom_ratio = (p_ref.Y() - m_rcVisible.Bottom()) / m_rcVisible.Height();
  303.     TModelUnit bottom = p_ref.Y() - new_h * bottom_ratio;
  304.     m_rcOrigVisible.SetBottom(bottom);
  305.     m_rcOrigVisible.SetTop(bottom + new_h); 
  306.     m_rcVisible = m_rcOrigVisible;
  307.     x_CorrectScale(m_rcVisible.CenterPoint());
  308.     x_ScaleToFitLimits(); 
  309.     x_ShiftToFitLimits();
  310.     x_AdjustVisibleRect();
  311. }
  312. void    CGlPane::SetScale(TModelUnit scale_x, TModelUnit scale_y)
  313. {
  314.     SetScale(scale_x, scale_y, m_rcVisible.CenterPoint());
  315. }
  316. // constraints forced by x_CorrectScale() may be conflicting with other constraints
  317. // in that case x_CorrectScale() has the lowerest priority
  318. // does not work on negative scales
  319. void    CGlPane::x_CorrectScale(TModelPoint p_center)
  320. {    
  321.     if(m_MinScaleX != 0)    {
  322.         TModelUnit scale_x = GetScaleX();
  323.         if(scale_x < m_MinScaleX)   {
  324.             scale_x = m_MinScaleX;
  325.         
  326.             TModelUnit new_w = m_rcVP.Width() * scale_x;
  327.             TModelUnit left = p_center.X() - new_w / 2;
  328.             m_rcOrigVisible.SetLeft(left);
  329.             m_rcOrigVisible.SetRight(left + new_w);
  330.         }
  331.     }
  332.     if(m_MinScaleY != 0)    {
  333.         TModelUnit scale_y = GetScaleY();
  334.         if(scale_y < m_MinScaleX)   {
  335.             scale_y = m_MinScaleY;
  336.         
  337.             TModelUnit new_h = m_rcVP.Height() * scale_y;
  338.             TModelUnit bottom = p_center.Y() - new_h / 2;
  339.             m_rcOrigVisible.SetBottom(bottom);
  340.             m_rcOrigVisible.SetTop(bottom + new_h);
  341.         }
  342.     }
  343. }
  344. // this funtions make sure that visible area is not larger then model limits
  345. // it works fine with negative scales
  346. void    CGlPane::x_ScaleToFitLimits(void)
  347. {
  348.     if(m_AdjustX & fScaleToLimits)  {
  349.         TModelUnit w = ::fabs(m_rcOrigVisible.Width());
  350.         if(w > ::fabs(m_rcLimits.Width())) {
  351.             m_rcOrigVisible.SetLeft(m_rcLimits.Left());
  352.             m_rcOrigVisible.SetRight(m_rcLimits.Right());
  353.         }
  354.     }
  355.     if(m_AdjustY & fScaleToLimits)  {
  356.         TModelUnit h = ::fabs(m_rcOrigVisible.Height());
  357.         if(h > ::fabs(m_rcLimits.Height())) {
  358.             m_rcOrigVisible.SetBottom(m_rcLimits.Bottom());
  359.             m_rcOrigVisible.SetTop(m_rcLimits.Top());
  360.         }
  361.     }
  362. }
  363. // Moves visible area so that it will be located within model limits.
  364. // If visible area is greater then limits rect, function aligns origin of the visible
  365. // rect with the origin of the limits rect and lets the other corner of visible rect
  366. // extend outside limits.
  367. // works on negative scales
  368. void CGlPane::x_ShiftToFitLimits(void)
  369. {    
  370.     if(m_AdjustX & fShiftToLimits)  { //horizontal adjustment
  371.         TModelUnit shift = 0;    
  372.         bool neg_range = m_rcLimits.Right() < m_rcLimits.Left();
  373.         TModelUnit left_shift = m_rcLimits.Left() - m_rcOrigVisible.Left();
  374.         TModelUnit right_shift = m_rcLimits.Right() - m_rcOrigVisible.Right();
  375.         shift = s_GetShift(left_shift, right_shift, neg_range, m_TypeX); 
  376.         m_rcOrigVisible.Offset(shift, 0);
  377.     }
  378.     if(m_AdjustY & fShiftToLimits)  { // vertical adjustment
  379.         TModelUnit shift = 0;    
  380.         bool neg_range = m_rcLimits.Top() < m_rcLimits.Bottom(); 
  381.         TModelUnit bottom_shift = m_rcLimits.Bottom() - m_rcOrigVisible.Bottom();
  382.         TModelUnit top_shift = m_rcLimits.Top() - m_rcOrigVisible.Top();
  383.     
  384.         shift = s_GetShift(bottom_shift, top_shift, neg_range, m_TypeY);
  385.         m_rcOrigVisible.Offset(0, shift);
  386.     }    
  387.     m_rcVisible = m_rcOrigVisible;
  388. }
  389. // adjust only m_rcVisible not m_rcOrigVisible
  390. // does not work on negative scales
  391. void    CGlPane::x_AdjustVisibleRect(void)
  392. {
  393.     TModelUnit scale_x = GetScaleX();
  394.     TModelUnit scale_y = GetScaleY();
  395.     TModelUnit new_scale_x = scale_x;
  396.     TModelUnit new_scale_y = scale_y;
  397.     
  398.     if(m_bProportionalMode) { 
  399.         new_scale_x = new_scale_y = max(scale_x, scale_y);
  400.     }    
  401.     // use scale to adjust m_rcVisible with regard to its origin
  402.     if (new_scale_x != scale_x) {
  403.         TModelUnit w = m_rcVP.Width() * new_scale_x;
  404.         TModelUnit left = m_rcOrigVisible.Left();
  405.         TModelUnit right = m_rcOrigVisible.Right();
  406.         switch(m_TypeX) {
  407.         case eOriginLeft:   right = left + w; break;
  408.         case eOriginRight:  left = right - w; break;
  409.         case eOriginCenter: {
  410.             left = (left + right - w) / 2;
  411.             right = left + w;
  412.         }; break;
  413.         case eOriginBottom:
  414.         case eOriginTop: _ASSERT(false); break; // invalid values
  415.         }
  416.         m_rcVisible.SetLeft(left);
  417.         m_rcVisible.SetRight(right);
  418.     }
  419.     if (new_scale_y != scale_y) {
  420.         TModelUnit h = m_rcVP.Height() * new_scale_y;
  421.         TModelUnit  top = m_rcOrigVisible.Top();
  422.         TModelUnit  bottom = m_rcOrigVisible.Bottom();
  423.         switch(m_TypeY) {
  424.         case eOriginBottom: top = bottom + h; break;
  425.         case eOriginTop: bottom = top - h; break;
  426.         case eOriginCenter: {
  427.             bottom = (top + bottom - h) / 2;
  428.             top = bottom + h;
  429.         }; break;
  430.         case eOriginLeft:
  431.         case eOriginRight: _ASSERT(false); break; // invalid values
  432.         }
  433.         m_rcVisible.SetBottom(bottom);
  434.         m_rcVisible.SetTop(top);
  435.     }
  436. }
  437. double  CGlPane::s_GetShift(TModelUnit low_shift, TModelUnit high_shift, bool neg_range, EOriginType type)
  438. {
  439.     TModelUnit shift = 0;
  440.     switch(type)    {
  441.     case eOriginBottom:
  442.     case eOriginLeft: {
  443.         if(neg_range)   {
  444.             if(low_shift < 0)
  445.                 shift = low_shift;
  446.             else if(high_shift > 0)
  447.                 shift = min(high_shift, low_shift);
  448.         } else {
  449.             if(low_shift > 0)
  450.                 shift = low_shift;
  451.             else if(high_shift < 0)
  452.                 shift = max(high_shift, low_shift);
  453.         }
  454.     }; break;
  455.     case eOriginRight:
  456.     case eOriginTop: {
  457.         if(neg_range)   {
  458.             if(high_shift > 0)
  459.                 shift = high_shift;
  460.             else if(low_shift < 0)
  461.                 shift = max(high_shift, low_shift);
  462.         } else {
  463.             if(high_shift < 0)
  464.                 shift = high_shift;
  465.             else if(low_shift > 0)
  466.                 shift = max(high_shift, low_shift);
  467.         }
  468.     }; break;
  469.     case eOriginCenter: {
  470.         shift = (low_shift + high_shift) / 2;
  471.     }; break;
  472.     } //switch
  473.     return shift;
  474. }
  475. ////////////////////////////////////////////////////////////////////////////////
  476. // Scroll functions
  477. bool    CGlPane::NeedsScrollX(void) const
  478. {
  479.     return (m_rcVisible.Left() > m_rcLimits.Left())
  480.             ||  (m_rcVisible.Right() < m_rcLimits.Right());
  481. }
  482. bool    CGlPane::NeedsScrollY(void) const
  483. {
  484.     TModelUnit d1 = ::fabs(m_rcVisible.Height());
  485.     TModelUnit d2 = ::fabs(m_rcLimits.Height());
  486.     return d1 < d2;
  487. }
  488. void    CGlPane::Scroll(TModelUnit dx, TModelUnit dy)
  489. {
  490.     m_rcOrigVisible.Offset(dx, dy);
  491.     m_rcVisible.Offset(dx, dy);
  492.     
  493.     x_ShiftToFitLimits();  
  494. }
  495. ////////////////////////////////////////////////////////////////////////////////
  496. // Coordinate transformations (Project - UnProject)
  497.     
  498. TVPUnit CGlPane::ProjectX(TModelUnit m_x) const
  499. {
  500.     _ASSERT(m_MatrixPolicy == eAlwaysUpdate);
  501.     if(m_bEnableOffset) {
  502.         m_x -= m_rcVisible.Left();
  503.     }
  504.     GLdouble x = 0;
  505.     GLdouble y = 0;
  506.     GLdouble z = 0;
  507.     gluProject( (GLdouble) m_x, 0.0, 0.0,  
  508.                 m_mxModelView, m_mxProjection, m_mxVP, &x, &y, &z);    
  509.     
  510.     return (TVPUnit) x;
  511. }
  512. TVPUnit CGlPane::ProjectY(TModelUnit m_y) const
  513. {
  514.     _ASSERT(m_MatrixPolicy == eAlwaysUpdate);
  515.     if(m_bEnableOffset) {
  516.         m_y -= m_rcVisible.Bottom();
  517.     }
  518.     GLdouble x = 0;
  519.     GLdouble y = 0;
  520.     GLdouble z = 0;
  521.     gluProject( 0.0, (GLdouble) m_y, 0.0,  
  522.                 m_mxModelView, m_mxProjection, m_mxVP, &x, &y, &z);    
  523.     if(m_bEnableOffset) {
  524.         y += m_rcVisible.Bottom();
  525.     }
  526.     return (TVPUnit) y;
  527. }
  528. TVPPoint    CGlPane::Project(TModelUnit m_x, TModelUnit m_y) const
  529. {
  530.     _ASSERT(m_MatrixPolicy == eAlwaysUpdate);
  531.     if(m_bEnableOffset) {
  532.         m_x -= m_rcVisible.Left();
  533.         m_y -= m_rcVisible.Bottom();
  534.     }
  535.     GLdouble x = 0;
  536.     GLdouble y = 0;
  537.     GLdouble z = 0;
  538.     gluProject( (GLdouble) m_x, (GLdouble) m_y, 0.0,  
  539.                 m_mxModelView, m_mxProjection, m_mxVP, &x, &y, &z);    
  540.     return TVPPoint((TVPUnit) x, (TVPUnit) y);
  541. }
  542. TModelUnit CGlPane::UnProjectX(TVPUnit m_x) const
  543. {
  544.     _ASSERT(m_MatrixPolicy == eAlwaysUpdate);
  545.     GLdouble x = 0;
  546.     GLdouble y = 0;
  547.     GLdouble z = 0;
  548.     gluUnProject( (GLdouble) m_x, 0.0, 0.0, 
  549.                    m_mxModelView, m_mxProjection, m_mxVP,
  550.                    &x, &y, &z);    
  551.     if(m_bEnableOffset) {
  552.         x += m_rcVisible.Left();
  553.     }    
  554.     return x;
  555. }
  556. TModelUnit CGlPane::UnProjectY(TVPUnit m_y) const
  557. {
  558.     _ASSERT(m_MatrixPolicy == eAlwaysUpdate);
  559.     
  560.     GLdouble x = 0;
  561.     GLdouble y = 0;
  562.     GLdouble z = 0;
  563.     gluUnProject( 0.0, (GLdouble) m_y, 0.0, 
  564.                   m_mxModelView, m_mxProjection, m_mxVP,
  565.                   &x, &y, &z);
  566.     if(m_bEnableOffset) {
  567.         y += m_rcVisible.Bottom();
  568.     }    
  569.     return y;
  570. }
  571. TModelPoint CGlPane::UnProject(TVPUnit m_x, TVPUnit m_y) const
  572. {
  573.     _ASSERT(m_MatrixPolicy == eAlwaysUpdate);
  574.     
  575.     GLdouble x = 0;
  576.     GLdouble y = 0;
  577.     GLdouble z = 0;
  578.     gluUnProject( (GLdouble) m_x, (GLdouble) m_y, 0.0, 
  579.                   m_mxModelView, m_mxProjection, m_mxVP,
  580.                   &x, &y, &z);
  581.     if(m_bEnableOffset) {
  582.         x += m_rcVisible.Left();
  583.         y += m_rcVisible.Bottom();
  584.     }    
  585.     return TModelPoint(x, y);
  586. }
  587. TModelUnit  CGlPane::UnProjectWidth(TVPUnit vp_w)
  588. {
  589.     _ASSERT(m_MatrixPolicy == eAlwaysUpdate);
  590.     
  591.     GLdouble x1 = 0;
  592.     GLdouble x2 = 0;
  593.     GLdouble y  = 0;
  594.     GLdouble z  = 0;
  595.     gluUnProject( 0.0, 0.0, 0.0, m_mxModelView, m_mxProjection, m_mxVP, &x1, &y, &z);
  596.     gluUnProject( vp_w, 0.0, 0.0, m_mxModelView, m_mxProjection, m_mxVP, &x2, &y, &z);    
  597.     return x2 - x1;
  598. }
  599. TModelUnit  CGlPane::UnProjectHeight(TVPUnit vp_h)
  600. {
  601.     _ASSERT(m_MatrixPolicy == eAlwaysUpdate);
  602.     
  603.     GLdouble x  = 0;
  604.     GLdouble y1 = 0;
  605.     GLdouble y2 = 0;
  606.     GLdouble z  = 0;
  607.     gluUnProject( 0.0, 0.0, 0.0, m_mxModelView, m_mxProjection, m_mxVP, &x, &y1, &z);
  608.     gluUnProject( 0.0, vp_h, 0.0, m_mxModelView, m_mxProjection, m_mxVP, &x, &y2, &z);    
  609.     return y2 - y1;
  610. }
  611. END_NCBI_SCOPE
  612. /*
  613.  * ===========================================================================
  614.  * $Log: glpane.cpp,v $
  615.  * Revision 1000.3  2004/06/01 20:50:55  gouriano
  616.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.11
  617.  *
  618.  * Revision 1.11  2004/05/21 22:27:45  gorelenk
  619.  * Added PCH ncbi_pch.hpp
  620.  *
  621.  * Revision 1.10  2004/04/08 13:51:11  dicuccio
  622.  * Initialize variables prior to calling glUnproject
  623.  *
  624.  * Revision 1.9  2003/12/08 15:07:48  yazhuk
  625.  * Workaround for OpenGL rounding/precision problems
  626.  *
  627.  * Revision 1.8  2003/11/17 20:28:22  yazhuk
  628.  * Introduced zoom options - added EZoomOptions and modified zoom functions.
  629.  *
  630.  * Revision 1.7  2003/10/29 22:24:02  yazhuk
  631.  * Added clipping capabilities, fixed SetScaleRefPoint()
  632.  *
  633.  * Revision 1.6  2003/10/27 19:57:51  dicuccio
  634.  * Removedcall to CGlUtils::CheckGlError()
  635.  *
  636.  * Revision 1.5  2003/10/22 18:26:45  lebedev
  637.  * SetScale method with reference point added
  638.  *
  639.  * Revision 1.4  2003/10/20 15:43:34  yazhuk
  640.  * Replaced boolean flags with EAdjustmentPolicy enumeration.
  641.  *
  642.  * Revision 1.3  2003/10/15 21:13:24  yazhuk
  643.  * Introduced projection matrix updating policy, fixed some minor problems
  644.  *
  645.  * Revision 1.2  2003/10/10 17:16:51  dicuccio
  646.  * Removed unnecessary call to CGlUtils::DumpState()
  647.  *
  648.  * Revision 1.1  2003/10/08 12:53:38  dicuccio
  649.  * Moved from gui/graph
  650.  *
  651.  * Revision 1.14  2003/10/07 20:56:39  yazhuk
  652.  * Added assertions, simplified destructor
  653.  *
  654.  * Revision 1.13  2003/10/03 16:24:49  yazhuk
  655.  * Modified open() functions so that OpenPixels() will not change projection matrices
  656.  *
  657.  * Revision 1.12  2003/09/30 18:19:36  yazhuk
  658.  * Fixed compilation problem in SetScale()
  659.  *
  660.  * Revision 1.11  2003/09/30 18:06:01  yazhuk
  661.  * Replaced fabs() with ::fabs()
  662.  *
  663.  * Revision 1.9  2003/09/25 20:35:49  yazhuk
  664.  * Added support for Visible rect adjustment
  665.  *
  666.  * Revision 1.8  2003/09/24 19:53:20  yazhuk
  667.  * Enforced coding policy. Fixed visible rect adjustment problems.
  668.  *
  669.  * Revision 1.7  2003/09/10 20:36:24  yazhuk
  670.  * Added GetScale() functions, modified ZoomAll(). Added glScissors() calls to
  671.  * Open() functions
  672.  *
  673.  * Revision 1.6  2003/08/28 19:20:10  yazhuk
  674.  * Implemented specification of the port origin and  autoadjustment of visible
  675.  * rect
  676.  *
  677.  * Revision 1.5  2003/08/14 17:58:55  yazhuk
  678.  * Changed default for m_bZoomEnY
  679.  *
  680.  * Revision 1.4  2003/08/11 16:10:57  yazhuk
  681.  * Compilation fixes for GCC
  682.  *
  683.  * Revision 1.3  2003/08/10 14:11:47  dicuccio
  684.  * Added makefiles for Unix projects; compilation fixes for gcc
  685.  *
  686.  * Revision 1.2  2003/08/08 15:59:36  yazhuk
  687.  * Comments added
  688.  *
  689.  * ===========================================================================
  690.  */