Back to index

salome-gui  6.5.0
GLViewer_ViewPort2d.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  Author : OPEN CASCADE
00024 // File:      GLViewer_ViewPort2d.cxx
00025 // Created:   November, 2004
00026 //
00027 /* GLViewer_ViewPort2d Source File */
00028 
00029 //#include <GLViewerAfx.h>
00030 #include "GLViewer_ViewPort2d.h"
00031 #include "GLViewer_Viewer2d.h"
00032 #include "GLViewer_ViewFrame.h"
00033 #include "GLViewer_MimeData.h"
00034 #include "GLViewer_Context.h"
00035 #include "GLViewer_Compass.h"
00036 #include "GLViewer_Grid.h"
00037 #include "GLViewer_Drawer.h"
00038 
00039 // TODO: Porting to Qt4
00040 //#include <QtxToolTip.h>
00041 
00042 #include <QHBoxLayout>
00043 #include <QMouseEvent>
00044 #include <QRect>
00045 //#include <QMenu>
00046 //#include <QToolTip>
00047 #include <QApplication>
00048 #include <QClipboard>
00049 #include <QBitmap>
00050 #include <QLabel>
00051 #include <QWidget>
00052 #include <QRubberBand>
00053 
00054 #define WIDTH       640
00055 #define HEIGHT      480
00056 #define MARGIN      100
00057 
00058 #define GRID_XSIZE  100
00059 #define GRID_YSIZE  100
00060 
00061 int static aLastViewPostId = 0;
00062 
00063 void rotate_point( float& theX, float& theY, float theAngle )
00064 {
00065     float aTempX = theX * cos(theAngle) - theY * sin(theAngle);
00066     float aTempY = theX * sin(theAngle) + theY * cos(theAngle);
00067     theX = aTempX;
00068     theY = aTempY;
00069 }
00070 
00074 GLViewer_ViewPort2d::GLViewer_ViewPort2d( QWidget* parent, GLViewer_ViewFrame* theViewFrame )
00075 : GLViewer_ViewPort( parent ),
00076   myMargin( MARGIN ), myWidth( WIDTH ), myHeight( HEIGHT ),
00077   myXScale( 1.0 ), myYScale( 1.0 ), myXOldScale( 1.0 ), myYOldScale( 1.0 ),
00078   myXPan( 0.0 ), myYPan( 0.0 ),
00079   myIsMouseReleaseBlock( false ),
00080   myRectBand( 0 )
00081 {
00082   if ( !theViewFrame )
00083     myViewFrame = (GLViewer_ViewFrame*)parent;
00084   else
00085     myViewFrame = theViewFrame;
00086 
00087   myGrid = 0;
00088   myCompass = 0;
00089   myBorder = new GLViewer_Rect();
00090 
00091   QBoxLayout* qbl = new QHBoxLayout( this );
00092   qbl->setSpacing( 0 );
00093   qbl->setMargin( 0 );
00094 
00095   myGLWidget = new GLViewer_Widget( this, 0 ) ;
00096   qbl->addWidget( myGLWidget );
00097   myGLWidget->setFocusProxy( this );
00098   setMouseTracking( TRUE );
00099 
00100   myIsDragProcess = noDrag;
00101   //myCurDragMousePos = QPoint();
00102   myCurDragPosX = NULL;
00103   myCurDragPosY = NULL;
00104 
00105   myIsPulling = false;
00106 
00107   myViewPortId = aLastViewPostId;
00108   aLastViewPostId++;
00109 
00110   mypFirstPoint = NULL;
00111   mypLastPoint = NULL;
00112 
00113     // TODO: Porting to Qt4
00114     /*myObjectTip = new QtxToolTip( myGLWidget );///GLViewer_ObjectTip( this );
00115     myObjectTip->setShowDelayTime( 60000 );
00116     connect( myObjectTip, SIGNAL( maybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ),
00117              this, SLOT( onMaybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ) );*/
00118 //    myGLWidget->installEventFilter( myObjectTip );
00119 }
00120 
00124 GLViewer_ViewPort2d::~GLViewer_ViewPort2d()
00125 {
00126     if( myCompass )
00127         delete myCompass;
00128 
00129     if( myGrid )
00130         delete myGrid;
00131 
00132     delete myBorder;
00133     delete myGLWidget;
00134 
00135     if ( myRectBand ) myRectBand->hide();
00136     delete myRectBand;
00137 }
00138 
00142 void GLViewer_ViewPort2d::onStartDragObject( )
00143 {
00144     if( myIsDragProcess == noDrag )
00145     {
00146         myIsDragProcess = initDrag;
00147         QCursor::setPos( (int)(*myCurDragPosX), (int)(*myCurDragPosY) );
00148         //myCurDragMousePos = QPoint( 0, 0 );
00149         delete myCurDragPosX;
00150         delete myCurDragPosY;
00151         myCurDragPosX = NULL;
00152         myCurDragPosY = NULL;
00153         return;
00154     }
00155 }
00156 
00160 void GLViewer_ViewPort2d::onCutObject()
00161 {
00162     /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
00163     if( aMovingObject )
00164     {
00165         GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
00166         aMimeSource->setObject( aMovingObject );
00167 
00168         QClipboard *aClipboard = QApplication::clipboard();
00169         aClipboard->clear();
00170         aClipboard->setData( aMimeSource );
00171 
00172         ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->deleteObject( aMovingObject );
00173     }*/
00174     GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
00175     int aObjNum = aContext->NbSelected();
00176     if( aObjNum > 0 )
00177     {
00178         QList<GLViewer_Object*> aObjects;
00179         GLViewer_MimeData* aMimeData = new GLViewer_MimeData();
00180         aContext->InitSelected();
00181         for( ; aContext->MoreSelected(); aContext->NextSelected() )
00182             aObjects.append( aContext->SelectedObject() );
00183 
00184         //aMimeData->setObjects( aObjects ); ouv 6.05.04
00185 
00186         QClipboard *aClipboard = QApplication::clipboard();
00187         aClipboard->clear();
00188         aClipboard->setMimeData( aMimeData );
00189 
00190         for( int i = 0; i < aObjNum; i++ )
00191             aContext->deleteObject( aObjects[i] );
00192     }
00193 }
00194 
00198 void GLViewer_ViewPort2d::onCopyObject()
00199 {
00200     /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
00201     if( aMovingObject )
00202     {
00203         GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
00204         aMimeSource->setObject( aMovingObject );
00205 
00206         QClipboard *aClipboard = QApplication::clipboard();
00207         aClipboard->clear();
00208         aClipboard->setData( aMimeSource );
00209     }
00210     */
00211     GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
00212     int aObjNum = aContext->NbSelected();
00213     if( aObjNum > 0 )
00214     {
00215         QList<GLViewer_Object*> aObjects;
00216         GLViewer_MimeData* aMimeData = new GLViewer_MimeData();
00217         aContext->InitSelected();
00218         for( ; aContext->MoreSelected(); aContext->NextSelected() )
00219             aObjects.append( aContext->SelectedObject() );
00220 
00221         //aMimeData->setObjects( aObjects ); ouv 6.05.04
00222 
00223         QClipboard *aClipboard = QApplication::clipboard();
00224         aClipboard->clear();
00225         aClipboard->setMimeData( aMimeData );
00226     }
00227 }
00228 
00232 void GLViewer_ViewPort2d::onPasteObject()
00233 {
00234     /*QClipboard *aClipboard = QApplication::clipboard();
00235     QMimeSource* aMimeSource = aClipboard->data();
00236     if( aMimeSource->provides( "GLViewer_Object" ) )
00237     {
00238         const char* aType;
00239         int i = 1;
00240         QByteArray anArray;
00241         do
00242         {
00243             aType = aMimeSource->format( i );
00244             anArray = aMimeSource->encodedData( aType );
00245             if( anArray.size() != 0 )
00246                 break;
00247             i++;
00248         }
00249         while( aType != 0 );
00250         if( anArray.size() == 0 )
00251             return;
00252 
00253         GLViewer_Object* aObject = GLViewer_MimeSource::getObject( anArray, aType );
00254         if( !aObject )
00255             return;
00256 
00257         ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->insertObject( aObject, true );
00258     }
00259     */
00260     /* ouv 6.05.04
00261     QClipboard *aClipboard = QApplication::clipboard();
00262 
00263     QMimeSource* aMimeSource = aClipboard->data();
00264     if( aMimeSource->provides( "GLViewer_Objects" ) )
00265     {
00266         QByteArray anArray = aMimeSource->encodedData( "GLViewer_Objects" );
00267         QList<GLViewer_Object*> aObjects = GLViewer_MimeSource::getObjects( anArray, "GLViewer_Objects" );
00268         if( aObjects.empty() )
00269             return;
00270         GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
00271         for( int i = 0; i < aObjects.count(); i++ )
00272             aContext->insertObject( aObjects[i], true );
00273     }
00274     */
00275 }
00276 
00280 void GLViewer_ViewPort2d::onDragObject( QMouseEvent* e )
00281 {
00282   //cout << "---GLViewer_ViewPort2d::onDragObject()---" << endl;
00283   GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
00284   GLViewer_Context* aContext = aViewer->getGLContext();
00285   GLViewer_Object* anObject = aContext->getCurrentObject();
00286 
00287   if( !aContext )
00288     return;
00289 
00290   float aX = e->pos().x();
00291   float anY = e->pos().y();
00292   aViewer->transPoint( aX, anY );
00293 
00294   if( myCurDragPosX == NULL && myCurDragPosY == NULL )
00295   {
00296     myCurDragPosX = new float(aX);
00297     myCurDragPosY = new float(anY);
00298     return;
00299   }
00300 
00301   //QPoint aNewPos = e->pos();
00302   //GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
00303 
00304   if( anObject && (e->buttons() & Qt::LeftButton ) )
00305   {
00306     if( aContext->isSelected( anObject ) )
00307     {
00308       for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
00309       {
00310         GLViewer_Object* aMovingObject = aContext->SelectedObject();
00311         if( aMovingObject )
00312           aMovingObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
00313       }
00314     }
00315     else
00316       anObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
00317   }
00318   else if( aContext->NbSelected() && (e->buttons() & Qt::MidButton ) )
00319     for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
00320         (aContext->SelectedObject())->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
00321 
00322   delete myCurDragPosX;
00323   delete myCurDragPosY;
00324   myCurDragPosX = new float(aX);
00325   myCurDragPosY = new float(anY);
00326 
00327   myGLWidget->updateGL();
00328 }
00329 
00333 void GLViewer_ViewPort2d::mousePressEvent( QMouseEvent* e )
00334 {
00335     emit vpMouseEvent( e );
00336 
00337     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
00338     GLViewer_Context* aContext = aViewer->getGLContext();
00339 
00340     GLViewer_Object* anObject = NULL;
00341     if( aContext )
00342         anObject = aContext->getCurrentObject();
00343 
00344     bool accel = e->modifiers() & GLViewer_ViewTransformer::accelKey();
00345     if( ( anObject && !( accel || e->button() == Qt::RightButton ) ) ||
00346         ( aContext->NbSelected() && !accel && e->button() == Qt::MidButton )  )
00347     {
00348         myIsDragProcess = inDrag;
00349     }
00350 }
00351 
00355 void GLViewer_ViewPort2d::mouseMoveEvent( QMouseEvent* e )
00356 {
00357     emit vpMouseEvent( e );
00358 
00359     if( myIsDragProcess == inDrag )
00360         onDragObject( e );
00361 
00362     /*GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
00363     GLViewer_Context* aContext = aViewer->getGLContext();
00364 
00365     GLViewer_Object* anObj = aContext->getCurrentObject();
00366     if( anObj && aContext->currentObjectIsChanged() )
00367     {
00368         //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::add}" << endl;
00369         //QToolTip::remove( myGLWidget );
00370         QRect* aRect = (aViewer->getWinObjectRect(anObj));
00371         //QToolTip::add( myGLWidget, *aRect, anObj->getToolTipText() );
00372         myGLWidget->addToolTip( anObj->getToolTipText(), *aRect );
00373     }
00374     if(!anObj)
00375     {
00376         //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::remove}" << endl;
00377         //QRect* aRect = (aViewer->getWinObjectRect(anObj));
00378         //QToolTip::remove( myGLWidget, *aRect );
00379         myGLWidget->removeToolTip();
00380     }*/
00381 }
00382 
00386 void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent* e )
00387 {
00388     if ( myIsMouseReleaseBlock )
00389     {
00390       // skip mouse release after double click
00391       myIsMouseReleaseBlock = false;
00392       return;
00393     }
00394 
00395     /* show popup menu */
00396     if ( e->button() == Qt::RightButton )
00397     {
00398         //QPopupMenu* popup = createPopup();
00399         //if ( popup && popup->count() )
00400         //    popup->exec( QCursor::pos() );
00401         //destroyPopup( /*popup*/ );
00402     }
00403     emit vpMouseEvent( e );
00404 
00405     if( myIsDragProcess == inDrag )
00406     {
00407       bool isAnyMoved = false;
00408       GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
00409       GLViewer_Context* aContext = aViewer->getGLContext();
00410       GLViewer_Object* aMovingObject;
00411       for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
00412       {
00413         aMovingObject = aContext->SelectedObject();
00414         if( aMovingObject )
00415           isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
00416       }
00417 
00418       aMovingObject = aContext->getCurrentObject();
00419       if( aMovingObject )
00420         isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
00421 
00422       myIsDragProcess = noDrag;
00423       //myCurDragMousePos.setX( 0 );
00424       //myCurDragMousePos.setY( 0 );
00425       delete myCurDragPosX;
00426       delete myCurDragPosY;
00427       myCurDragPosX = NULL;
00428       myCurDragPosY = NULL;
00429 
00430       if( isAnyMoved )
00431       {
00432         emit objectMoved();
00433         aViewer->updateBorders();
00434       }
00435     }
00436 }
00437 
00441 void GLViewer_ViewPort2d::mouseDoubleClickEvent( QMouseEvent * e )
00442 {
00443   //redefined to block mouse release after mouse double click
00444   myIsMouseReleaseBlock = true;
00445   // invoke base implementation
00446   GLViewer_ViewPort::mouseDoubleClickEvent( e );
00447 }
00448 
00453 void GLViewer_ViewPort2d::turnCompass( GLboolean on )
00454 {
00455     if( on )
00456         myCompass = new GLViewer_Compass( Qt::green, 30, GLViewer_Compass::TopRight, 10, 5, 12, 3 );
00457     else if( myCompass )
00458         delete myCompass;
00459 }
00460 
00465 void GLViewer_ViewPort2d::turnGrid( GLboolean on )
00466 {
00467     if( on )
00468     {
00469         myGrid = new GLViewer_Grid( 2*WIDTH, 2*HEIGHT,
00470                                     2*WIDTH, 2*HEIGHT,
00471                                     GRID_XSIZE, GRID_YSIZE,
00472                                     myXPan, myYPan,
00473                                     myXScale, myYScale );
00474     }
00475     else if( myGrid )
00476         delete myGrid;
00477 }
00478 
00484 void GLViewer_ViewPort2d::setGridColor( const QColor gridColor, const QColor axisColor )
00485 {
00486     if( myGrid )
00487     {
00488         myGrid->setGridColor( ( GLfloat )gridColor.red() / 255,
00489                   ( GLfloat )gridColor.green() / 255,
00490                   ( GLfloat )gridColor.blue() / 255 );
00491         myGrid->setAxisColor( ( GLfloat )axisColor.red() / 255,
00492                   ( GLfloat )axisColor.green() / 255,
00493                   ( GLfloat )axisColor.blue() / 255 );
00494     }
00495 }
00496 
00501 void GLViewer_ViewPort2d::setBackgroundColor( const QColor& color )
00502 {
00503     GLViewer_ViewPort::setBackgroundColor( color );
00504     myGLWidget->makeCurrent();
00505     glClearColor( ( GLfloat )color.red() / 255,
00506             ( GLfloat )color.green() / 255,
00507             ( GLfloat )color.blue() / 255, 1.0 );
00508     myGLWidget->repaint();
00509 }
00510 
00514 QColor GLViewer_ViewPort2d::backgroundColor() const
00515 {
00516     return GLViewer_ViewPort::backgroundColor();
00517 }
00518 
00522 void GLViewer_ViewPort2d::initResize( int x, int y )
00523 {
00524     float xa, xb, ya, yb;
00525     xa = myBorder->left() - myMargin;
00526     xb = myBorder->right() + myMargin;
00527     ya = myBorder->top() - myMargin;
00528     yb = myBorder->bottom() + myMargin;
00529 
00530     GLfloat zoom, xzoom, yzoom;
00531     GLfloat w = x;
00532     GLfloat h = y;
00533     bool max = FALSE;
00534 
00535     xzoom = (GLfloat)x / myWidth;
00536     yzoom = (GLfloat)y / myHeight;
00537 
00538     if ( ( xzoom < yzoom ) && ( xzoom < 1 ) )
00539         zoom = xzoom;
00540     else if ( ( yzoom < xzoom ) && ( yzoom < 1 ) )
00541         zoom = yzoom;
00542     else
00543     {
00544         max = TRUE;
00545         zoom = xzoom > yzoom ? xzoom : yzoom;
00546     }
00547 
00548     if ( !max && ( ! ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
00549              ( ( myXPan - w/2 ) > xa * myXScale * zoom ) ||
00550              ( ( myYPan + h/2 ) < yb * myYScale * zoom ) ||
00551              ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) )
00552         zoom = 1;
00553 
00554     if ( max && ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
00555             ( ( myXPan - w/2 ) > xa * myXScale * zoom ) ||
00556             ( ( myYPan + h/2 ) < yb * myYScale * zoom ) ||
00557             ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) )
00558         zoom = 1;
00559 
00560     myWidth = x;
00561     myHeight = y;
00562 
00563     myXScale *= zoom;
00564     myYScale = myXScale;
00565 
00566     if ( myGrid )
00567         myGrid->setResize( 2*x, 2*y, zoom );
00568 
00569     myGLWidget->setScale( myXScale, myYScale, 1.0 );
00570 }
00571 
00575 void GLViewer_ViewPort2d::paintEvent( QPaintEvent* e )
00576 {
00577     //cout << "GLViewer_ViewPort2d::paintEvent" << endl;
00578     myGLWidget->updateGL();
00579     GLViewer_ViewPort::paintEvent( e );
00580 }
00581 
00585 void GLViewer_ViewPort2d::resizeEvent( QResizeEvent* e )
00586 {
00587     //cout << "GLViewer_ViewPort2d::resizeEvent" << endl;
00588     GLViewer_ViewPort::resizeEvent( e );
00589 }
00590 
00594 void GLViewer_ViewPort2d::reset()
00595 {
00596     //cout << "GLViewer_ViewPort2d::reset" << endl;
00597 
00598     GLint val[4];
00599     GLint vpWidth, vpHeight;
00600 
00601     myGLWidget->makeCurrent();
00602     glGetIntegerv( GL_VIEWPORT, val );
00603     vpWidth = val[2];
00604     vpHeight = val[3];
00605 
00606     GLint w = myGLWidget->getWidth();
00607     GLint h = myGLWidget->getHeight();
00608     GLfloat zoom = vpWidth / ( GLfloat )w < vpHeight / ( GLfloat )h ?
00609                  vpWidth / ( GLfloat )w : vpHeight / ( GLfloat )h;
00610 
00611     if( myGrid )
00612     {
00613         myGrid->setPan( 0.0, 0.0 );
00614         myGrid->setZoom( zoom / myXScale );
00615     }
00616 
00617     myXPan = 0.0;
00618     myYPan = 0.0;
00619     myXScale = zoom;
00620     myYScale = zoom;
00621 
00622     myGLWidget->setPan( myXPan, myYPan, 0.0 );
00623     myGLWidget->setScale( myXScale, myYScale, 1.0 );
00624     myGLWidget->setRotationAngle( 0.0 );
00625     myGLWidget->setRotation( 0.0, 0.0, 0.0, 1.0 );
00626     myGLWidget->updateGL();
00627 }
00628 
00634 void GLViewer_ViewPort2d::pan( int dx, int dy )
00635 {
00636     //cout << "GLViewer_ViewPort2d::pan " << dx << " " << dy << endl;
00637 
00638     /*myXPan += dx / myXScale;
00639     myYPan += dy / myYScale;
00640 
00641     float ra, rx, ry, rz;
00642     myGLWidget->getRotation( ra, rx, ry, rz );
00643     GLfloat angle = ra * PI / 180.;
00644 
00645     if( myGrid )
00646         myGrid->setPan( myXPan*cos(angle) + myYPan*sin(angle),
00647                         -myXPan*sin(angle) + myYPan*cos(angle) );
00648 
00649     */
00650     float ra, rx, ry, rz;
00651     myGLWidget->getRotation( ra, rx, ry, rz );
00652     GLfloat angle = ra * PI / 180.;
00653 
00654     myXPan += (dx*cos(angle) + dy*sin(angle)) / myXScale;
00655     myYPan += (-dx*sin(angle) + dy*cos(angle)) / myXScale;
00656 
00657     if( myGrid )
00658         myGrid->setPan( myXPan, myYPan );
00659 
00660     myGLWidget->setPan( myXPan, myYPan, 0.0 );
00661     myGLWidget->setScale( myXScale, myYScale, 1.0 );
00662     myGLWidget->updateGL();
00663 }
00664 
00669 void GLViewer_ViewPort2d::setCenter( int x, int y )
00670 {
00671     //cout << "GLViewer_ViewPort2d::setCenter" << endl;
00672 
00673     GLint val[4];
00674     GLint vpWidth, vpHeight;
00675 
00676     myGLWidget->makeCurrent();
00677     glGetIntegerv( GL_VIEWPORT, val );
00678     vpWidth = val[2];
00679     vpHeight = val[3];
00680 
00681     myXPan -= ( x - vpWidth/2 ) / myXScale;
00682     myYPan += ( y - vpHeight/2 ) / myYScale;
00683 
00684     if( myGrid )
00685     {
00686         myGrid->setPan( myXPan, myYPan );
00687         myGrid->setZoom( myXOldScale / myXScale );
00688     }
00689 
00690     myXScale = myXOldScale;
00691     myYScale = myYOldScale;
00692 
00693     myGLWidget->setPan( myXPan, myYPan, 0.0 );
00694     myGLWidget->setScale( myXScale, myYScale, 1.0 );
00695     myGLWidget->updateGL();
00696 }
00697 
00701 void GLViewer_ViewPort2d::zoom( int x0, int y0, int x, int y )
00702 {
00703     //cout << "GLViewer_ViewPort2d::zoom" << endl;
00704 
00705     float dx, dy, zm;
00706     dx = x - x0;
00707     dy = y - y0;
00708 
00709     if ( dx == 0. && dy == 0. )
00710         return;
00711 
00712     zm = sqrt(dx * dx + dy * dy) / 100. + 1;
00713     zm = (dx > 0.) ?  zm : 1. / zm;
00714 
00715     //backup values
00716     float bX = myXScale;
00717     float bY = myYScale;
00718     myXScale *= zm;
00719     myYScale *= zm;
00720 
00721     if( myGrid )
00722     {
00723         if( myGrid->setZoom( zm ) )
00724         {
00725             myGLWidget->setPan( myXPan, myYPan, 0.0 );
00726             myGLWidget->setScale( myXScale, myYScale, 1.0 );
00727             myGLWidget->updateGL();
00728         }
00729         else
00730         {// undo
00731             myXScale = bX;
00732             myYScale = bY;
00733         }
00734     }
00735     else
00736     {
00737         myGLWidget->setPan( myXPan, myYPan, 0.0 );
00738         myGLWidget->setScale( myXScale, myYScale, 1.0 );
00739         myGLWidget->updateGL();
00740     }
00741 }
00742 
00747 void GLViewer_ViewPort2d::fitRect( const QRect& rect )
00748 {
00749     float x0, x1, y0, y1;
00750     float dx, dy, zm, centerX, centerY;
00751 
00752     GLint val[4];
00753     GLint vpWidth, vpHeight;
00754 
00755     myGLWidget->makeCurrent();
00756     glGetIntegerv( GL_VIEWPORT, val );
00757     vpWidth = val[2];
00758     vpHeight = val[3];
00759 
00760     x0 = rect.left();
00761     x1 = rect.right();
00762     y0 = rect.top();
00763     y1 = rect.bottom();
00764 
00765     dx = fabs( x1 - x0 );
00766     dy = fabs( y1 - y0 );
00767     centerX = ( x0 + x1 ) / 2.;
00768     centerY = ( y0 + y1 ) / 2.;
00769 
00770     if ( dx == 0. || dy == 0. )
00771         return;
00772 
00773     zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy;
00774 
00775     float aDX = ( vpWidth / 2. - centerX ) / myXScale;
00776     float aDY = ( vpHeight / 2. - centerY ) / myYScale;
00777 
00778     float ra, rx, ry, rz;
00779     myGLWidget->getRotation( ra, rx, ry, rz );
00780     GLfloat angle = ra * PI / 180.;
00781 
00782     myXPan += (aDX*cos(angle) - aDY*sin(angle));
00783     myYPan -= (aDX*sin(angle) + aDY*cos(angle));
00784 
00785     if( myGrid )
00786         myGrid->setPan( myXPan, myYPan );
00787 
00788     myXScale *= zm;
00789     myYScale = myXScale;
00790 
00791     if( myGrid )
00792         myGrid->setZoom( zm );
00793 
00794     myGLWidget->setPan( myXPan, myYPan, 0.0 );
00795     myGLWidget->setScale( myXScale, myYScale, 1.0 );
00796     myGLWidget->updateGL();
00797 }
00798 
00802 void GLViewer_ViewPort2d::fitSelect()
00803 {
00804   GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
00805   GLViewer_Context* aContext = aViewer->getGLContext();
00806   if( !aContext )
00807     return;
00808 
00809   QRect aSelRect;
00810   for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
00811     aSelRect |= *(aViewer->getWinObjectRect( aContext->SelectedObject() ));
00812 
00813   if( aSelRect.isValid() )
00814   {
00815     aSelRect.setTop( aSelRect.top() - SELECTION_RECT_GAP );
00816     aSelRect.setBottom( aSelRect.bottom() + SELECTION_RECT_GAP );
00817     aSelRect.setLeft( aSelRect.left() - SELECTION_RECT_GAP );
00818     aSelRect.setRight( aSelRect.right() + SELECTION_RECT_GAP );
00819     fitRect( aSelRect );
00820   }
00821 }
00822 
00827 void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
00828 {
00829     //cout << "GLViewer_ViewPort2d::fitAll" << endl;
00830 
00831     float xa, xb, ya, yb;
00832     float dx, dy, zm;
00833     float xScale, yScale;
00834 
00835     myMargin = qMax( myBorder->width(), myBorder->height() ) / 5;
00836 
00837     xa = myBorder->left() - myMargin;
00838     xb = myBorder->right() + myMargin;
00839     ya = myBorder->bottom() - myMargin;
00840     yb = myBorder->top() + myMargin;
00841 
00842     float aPoints[8] = { xa, ya, xb, ya, xa, yb, xb, yb };
00843 
00844     float ra, rx, ry, rz;
00845     myGLWidget->getRotation( ra, rx, ry, rz );
00846     float angle = ra * PI / 180.;
00847 
00848     int i;
00849     for( i = 0; i < 7; i = i + 2 )
00850         rotate_point( aPoints[i], aPoints[i+1], angle );
00851 
00852     float aBorders[4] = { aPoints[0], aPoints[0], aPoints[1], aPoints[1] };
00853 
00854     for( i = 2; i < 7; i = i + 2 )
00855     {
00856         if( aBorders[0] < aPoints[i] )
00857             aBorders[0] = aPoints[i];
00858         if( aBorders[1] > aPoints[i] )
00859             aBorders[1] = aPoints[i];
00860 
00861         if( aBorders[2] < aPoints[i+1] )
00862             aBorders[2] = aPoints[i+1];
00863         if( aBorders[3] > aPoints[i+1] )
00864             aBorders[3] = aPoints[i+1];
00865     }
00866 
00867     GLint val[4];
00868     GLint vpWidth, vpHeight;
00869 
00870     myGLWidget->makeCurrent();
00871     glGetIntegerv( GL_VIEWPORT, val );
00872     vpWidth = val[2];
00873     vpHeight = val[3];
00874 
00875     dx = fabs( aBorders[1] - aBorders[0] );
00876     dy = fabs( aBorders[3] - aBorders[2] );
00877 
00878     myXPan = -( aBorders[0] + aBorders[1] ) / 2;
00879     myYPan = -( aBorders[2] + aBorders[3] ) / 2;
00880 
00881 
00882     if( keepScale )
00883     {
00884         myXOldScale = myXScale;
00885         myYOldScale = myYScale;
00886     }
00887 
00888     xScale = myXScale;
00889     yScale = myYScale;
00890     if( dx && dy )
00891         zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy;
00892     else
00893         zm = 1.0;
00894     myXScale = zm;
00895     myYScale = zm;
00896 
00897 
00898     if( myGrid )
00899     {
00900         myGrid->setPan( myXPan, myYPan );
00901         if( dx > dy )
00902             myGrid->setZoom(  zm / xScale );
00903         else
00904             myGrid->setZoom( zm / yScale );
00905     }
00906 
00907     myGLWidget->setPan( myXPan, myYPan, 0.0 );
00908     myGLWidget->setScale( myXScale, myYScale, 1.0 );
00909     myGLWidget->updateGL();
00910 
00911     if( keepScale )
00912         emit vpUpdateValues();
00913 }
00914 
00919 void GLViewer_ViewPort2d::startRotation( int x, int y )
00920 {
00921     myGLWidget->setRotationStart( x, y, 1.0 );
00922 }
00923 
00928 void GLViewer_ViewPort2d::rotate( int intX, int intY )
00929 {
00930     GLint val[4];
00931     GLint vpWidth, vpHeight;
00932 
00933     myGLWidget->makeCurrent();
00934     glGetIntegerv( GL_VIEWPORT, val );
00935     vpWidth = val[2];
00936     vpHeight = val[3];
00937 
00938     float x = intX, y = intY;
00939     float x0 = vpWidth/2;
00940     float y0 = vpHeight/2;
00941 
00942     float xs, ys, zs, dx, dy;
00943     myGLWidget->getRotationStart( xs, ys, zs );
00944 
00945     xs = xs - x0;
00946     x = x - x0;
00947     dx = x - xs;
00948     ys = y0 - ys;
00949     y = y0 - y;
00950     dy = y - ys;
00951 
00952     float l1 = pow( double( xs*xs + ys*ys ), 0.5 );
00953     float l2 = pow( double( x*x + y*y ), 0.5 );
00954     float l = pow( double( dx*dx + dy*dy ), 0.5 );
00955 
00956     double mult = xs * y - x * ys;
00957     short sign;
00958     if( mult > 0 ) sign = 1;
00959     else if( mult < 0 ) sign = -1;
00960     else sign = 0;
00961 
00962     float anglePrev = myGLWidget->getRotationAngle();
00963     float angleNew = sign * acos( ( l1*l1 + l2*l2 - l*l ) / ( 2 * l1 * l2 )) * 180. / PI;
00964     float angle = anglePrev + angleNew;
00965 
00966     // GLfloat anAngle = angle * PI / 180.; unused
00967 
00968     float ra, rx, ry, rz;
00969     myGLWidget->getRotation( ra, rx, ry, rz );
00970     myGLWidget->setRotation( angle, rx, ry, rz );
00971     myGLWidget->updateGL();
00972 }
00973 
00977 void GLViewer_ViewPort2d::endRotation()
00978 {
00979     float ra, rx, ry, rz;
00980     myGLWidget->getRotation( ra, rx, ry, rz );
00981     myGLWidget->setRotationAngle( ra );
00982 }
00983 
00987 void GLViewer_ViewPort2d::drawCompass()
00988 {
00989     if( !myCompass->getVisible() )
00990         return;
00991 
00992     GLfloat xScale, yScale, xPan, yPan;
00993 
00994     int xPos = getWidth();
00995     int yPos = getHeight();
00996 
00997     int cPos = myCompass->getPos();
00998     int cSize = myCompass->getSize();
00999     QColor cCol = myCompass->getColor();
01000     int cWidthTop = myCompass->getArrowWidthTop();
01001     int cWidthBot = myCompass->getArrowWidthBottom();
01002     int cHeightTop = myCompass->getArrowHeightTop();
01003     int cHeightBot = myCompass->getArrowHeightBottom();
01004 
01005     GLfloat colorR = (cCol.red())/255;
01006     GLfloat colorG = (cCol.green())/255;
01007     GLfloat colorB = (cCol.blue())/255;
01008 
01009     float delX = cSize * 0.5;
01010     float delY = cSize * 0.5;
01011 
01012     getScale( xScale, yScale );
01013     getPan( xPan, yPan);
01014 
01015     float centerX = (xPos/2 - delX - cSize)/xScale;
01016     float centerY = (yPos/2 - delY - cSize)/yScale;
01017 
01018     switch ( cPos )
01019     {
01020     case GLViewer_Compass::TopLeft:
01021             centerX = -centerX;
01022             break;
01023         case GLViewer_Compass::BottomLeft:
01024             centerX = -centerX;
01025             centerY = -centerY;
01026             break;
01027         case GLViewer_Compass::BottomRight:
01028             centerY = -centerY;
01029             break;
01030         default: break;
01031     }
01032 
01033     float ra, rx, ry, rz;
01034     myGLWidget->getRotation( ra, rx, ry, rz );
01035     GLfloat angle = ra * PI / 180.;
01036     GLfloat /*r = 0.0,*/ x = 0.0 , y = 0.0;
01037 
01038     rotate_point( centerX, centerY, -angle );
01039 
01040     centerX -= xPan;
01041     centerY -= yPan;
01042 
01043     glColor3f( colorR, colorG, colorB );
01044     glBegin( GL_POLYGON );
01045     //arrow
01046         x = centerX;                      y = centerY + cSize / yScale;
01047         glVertex2f( x, y );
01048         //point #2
01049         x = centerX + cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
01050         glVertex2f( x, y );
01051         //point #3
01052         x = centerX + cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
01053         glVertex2f( x, y );
01054         //point #4
01055         x = centerX + cWidthBot / xScale; y = centerY - cSize/yScale;
01056         glVertex2f( x, y );
01057         //point #5
01058         x = centerX;                      y = centerY - (cSize - cHeightBot) / yScale ;
01059         glVertex2f( x, y );
01060         //point #6
01061         x = centerX - cWidthBot / xScale; y = centerY - cSize/yScale;
01062         glVertex2f( x, y );
01063         //point #7
01064         x = centerX - cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
01065         glVertex2f( x, y );
01066         //point #8
01067         x = centerX - cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
01068         glVertex2f( x, y );
01069     glEnd();
01070     glLineWidth( 2.0 );
01071     glEnable( GL_LINE_SMOOTH );
01072     glBegin(GL_LINE_LOOP);
01073     //circle
01074         float aCircAngle = 0;
01075         for ( int i = 0; i < 20 * SEGMENTS + 1; i++ )
01076         {
01077             x = centerX + cos(aCircAngle) * cSize / xScale;
01078             y = centerY + sin(aCircAngle) * cSize / yScale;
01079             glVertex2f( x, y );
01080             aCircAngle += float( STEP ) / 2;
01081         }
01082     glEnd();
01083 
01084     GLdouble        modelMatrix[16], projMatrix[16];
01085     GLint           viewport[4];
01086     GLdouble        winxN, winyN, winz;
01087     GLdouble        winxE, winyE;
01088     GLdouble        winxS, winyS;
01089     GLdouble        winxW, winyW;
01090     GLuint          aTextList;
01091 
01092     GLViewer_TexFont* aFont = myCompass->getFont();
01093     float widN = (float)aFont->getStringWidth( "N" );
01094     float widW = (float)aFont->getStringWidth( "W" );
01095     float widS = (float)aFont->getStringWidth( "S" );
01096     float widE = (float)aFont->getStringWidth( "E" );
01097     float heightL = (float)aFont->getStringHeight();
01098 
01099     float xGapN = - widN/2 *( 1.0 + sin(angle) );
01100     float xGapS = - widS/2 *( 1.0 - sin(angle) );
01101     float xGapW = - widW/2 *( 1.0 + cos(angle) );
01102     float xGapE = - widE/2 *( 1.0 - cos(angle) );
01103 
01104     float yGapN = - heightL/2 *( 1.0 - cos(angle) ) * 0.75;
01105     float yGapS = - heightL/2 *( 1.0 + cos(angle) ) * 0.75;
01106     float yGapW = - heightL/2 *( 1.0 + sin(angle) ) * 0.75;
01107     float yGapE = - heightL/2 *( 1.0 - sin(angle) ) * 0.75;
01108 
01109     glGetIntegerv (GL_VIEWPORT, viewport);
01110     glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
01111     glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
01112 
01113     gluProject (centerX, centerY + cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxN, &winyN, &winz);
01114     gluProject (centerX + cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxE, &winyE, &winz);
01115     gluProject (centerX, centerY - cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxS, &winyS, &winz);
01116     gluProject (centerX - cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxW, &winyW, &winz);
01117 
01118     glColor3f( 1.0, 1.0, 1.0 );
01119 
01120     aTextList = glGenLists( 1 );
01121     glNewList( aTextList, GL_COMPILE );
01122 
01123     glMatrixMode(GL_PROJECTION);
01124     glPushMatrix();
01125     glLoadIdentity();
01126     glOrtho(0,viewport[2],0,viewport[3],-100,100);
01127     glMatrixMode(GL_MODELVIEW);
01128     glPushMatrix();
01129     glLoadIdentity();
01130 
01131     aFont->drawString( "N", winxN + xGapN, winyN + yGapN );
01132     aFont->drawString( "E", winxE + xGapE, winyE + yGapE );
01133     aFont->drawString( "S", winxS + xGapS, winyS + yGapS );
01134     aFont->drawString( "W", winxW + xGapW, winyW + yGapW );
01135 
01136     glMatrixMode(GL_PROJECTION);
01137     glPopMatrix();
01138     glMatrixMode(GL_MODELVIEW);
01139     glPopMatrix();
01140 
01141     glEndList();
01142 
01143     if ( aTextList != -1 )
01144         glCallList( aTextList );
01145 }
01146 
01150 BlockStatus GLViewer_ViewPort2d::currentBlock()
01151 {
01152     if( myIsDragProcess == inDrag && myCurDragPosX != NULL && myCurDragPosY != NULL)
01153         return BlockStatus(BS_Highlighting | BS_Selection);
01154 
01155     if( mypFirstPoint && mypLastPoint )
01156         return BlockStatus(BS_Highlighting | BS_Selection);
01157 
01158     return BS_NoBlock;
01159 }
01160 
01165 void GLViewer_ViewPort2d::startSelectByRect( int x, int y )
01166 {
01167     if( !mypFirstPoint && !mypLastPoint )
01168     {
01169         mypFirstPoint = new QPoint( x, y );
01170         mypLastPoint = new QPoint( x, y );
01171     }
01172 
01173     if ( !myRectBand ) {
01174       myRectBand = new QRubberBand( QRubberBand::Rectangle, this );
01175       QPalette palette;
01176       palette.setColor(myRectBand->foregroundRole(), Qt::white);
01177       myRectBand->setPalette(palette);
01178     }
01179     myRectBand->hide();
01180 }
01181 
01186 void GLViewer_ViewPort2d::drawSelectByRect( int x, int y )
01187 {
01188     if( mypFirstPoint && mypLastPoint )
01189     {
01190         myRectBand->hide();    /* erase */
01191 
01192         mypLastPoint->setX( x );
01193         mypLastPoint->setY( y );
01194 
01195         QRect aRect = selectionRect();
01196         myRectBand->setGeometry( aRect );    /* draw */
01197         myRectBand->setVisible( aRect.isValid() );
01198     }
01199 
01200 }
01201 
01205 void GLViewer_ViewPort2d::finishSelectByRect()
01206 {
01207     if( mypFirstPoint && mypLastPoint )
01208     {
01209 
01210 
01211         if ( myRectBand ) myRectBand->hide();    /* erase */
01212 
01213         delete mypFirstPoint;
01214         delete mypLastPoint;
01215 
01216         mypFirstPoint = NULL;
01217         mypLastPoint = NULL;
01218 
01219         delete myRectBand;
01220         myRectBand = 0;
01221     }
01222 }
01223 
01227 QRect GLViewer_ViewPort2d::selectionRect()
01228 {
01229     QRect aRect;
01230     if( mypFirstPoint && mypLastPoint )
01231     {
01232         aRect.setLeft( qMin( mypFirstPoint->x(), mypLastPoint->x() ) );
01233         aRect.setTop( qMin( mypFirstPoint->y(), mypLastPoint->y() ) );
01234         aRect.setRight( qMax( mypFirstPoint->x(), mypLastPoint->x() ) );
01235         aRect.setBottom( qMax( mypFirstPoint->y(), mypLastPoint->y() ) );
01236     }
01237 
01238     return aRect;
01239 }
01240 
01243 bool GLViewer_ViewPort2d::startPulling( GLViewer_Pnt point )
01244 {
01245     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
01246     GLViewer_Context* aContext = aViewer->getGLContext();
01247     ObjList anObjects = aContext->getObjects();
01248 
01249     for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
01250     {
01251         GLViewer_Object* anObject = *it;
01252         GLViewer_Rect aRect = anObject->getPullingRect();
01253 
01254         if( aRect.contains( point ) && anObject->startPulling( point ) )
01255         {
01256             myIsPulling = true;
01257             myPullingObject = anObject;
01258             setCursor( *getHandCursor() );
01259             return true;
01260         }
01261     }
01262 
01263     return false;
01264 }
01265 
01268 void GLViewer_ViewPort2d::drawPulling( GLViewer_Pnt point )
01269 {
01270     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
01271     GLViewer_Context* aContext = aViewer->getGLContext();
01272     ObjList anObjects = aContext->getObjects();
01273 
01274     GLViewer_Object* aLockedObject = 0;
01275     for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
01276     {
01277         GLViewer_Object* anObject = *it;
01278         if( !anObject->getVisible() )
01279             continue;
01280 
01281         GLViewer_Rect aRect = anObject->getPullingRect();
01282 
01283         if( aRect.contains( point ) && anObject->portContains( point ) )
01284         {
01285             aLockedObject = anObject;
01286             break;
01287         }
01288     }
01289 
01290     myPullingObject->pull( point, aLockedObject );
01291 }
01292 
01295 void GLViewer_ViewPort2d::finishPulling()
01296 {
01297     myIsPulling = false;
01298     myPullingObject->finishPulling();
01299     setCursor( *getDefaultCursor() );
01300 }
01301 
01306 GLViewer_Rect GLViewer_ViewPort2d::win2GLV( const QRect& theRect ) const
01307 {
01308   GLViewer_Rect aRect;
01309 
01310   GLdouble        modelMatrix[16], projMatrix[16];
01311   GLint           viewport[4];
01312 
01313   GLdouble        objx1, objy1;
01314   GLdouble        objx2, objy2;
01315   GLdouble        objz;
01316 
01317   glGetIntegerv (GL_VIEWPORT, viewport);
01318   glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
01319   glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
01320 
01321   gluUnProject( theRect.left(), viewport[3] - theRect.top(), 0, modelMatrix, projMatrix, viewport, &objx1, &objy1, &objz );
01322   gluUnProject( theRect.right(), viewport[3] - theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &objx2, &objy2, &objz );
01323 
01324   aRect.setLeft( objx1 );
01325   aRect.setTop( objy1 );
01326   aRect.setRight( objx2 );
01327   aRect.setBottom( objy2 );
01328 
01329   return aRect;
01330 }
01331 
01336 QRect GLViewer_ViewPort2d::GLV2win( const GLViewer_Rect& theRect ) const
01337 {
01338   QRect aRect;
01339 
01340   GLdouble        modelMatrix[16], projMatrix[16];
01341   GLint           viewport[4];
01342 
01343   GLdouble        winx1, winy1;
01344   GLdouble        winx2, winy2;
01345   GLdouble        winz;
01346 
01347   glGetIntegerv (GL_VIEWPORT, viewport);
01348   glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
01349   glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
01350 
01351   gluProject( theRect.left(), theRect.top(), 0, modelMatrix, projMatrix, viewport, &winx1, &winy1, &winz );
01352   gluProject( theRect.right(), theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &winx2, &winy2, &winz );
01353 
01354   aRect.setLeft( (int)winx1 );
01355   aRect.setTop( viewport[3] - (int)winy1 );
01356   aRect.setRight( (int)winx2 );
01357   aRect.setBottom( viewport[3] - (int)winy2 );
01358 
01359   return aRect;
01360 }
01361 
01365 void GLViewer_ViewPort2d::onMaybeTip( QPoint thePoint, QString& theText, QFont& theFont, QRect& theTextReg, QRect& theRegion )
01366 {
01367   GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
01368 
01369   GLViewer_Object* anObj = aContext->getCurrentObject();
01370   if( anObj )
01371   {
01372     theText = anObj->getToolTipText();
01373     if( theText.isEmpty() )
01374       theText = anObj->getName();
01375 
01376     QStringList aList;
01377     if( anObj->isTooTipHTML() )
01378       aList = theText.split( "<br>", QString::SkipEmptyParts );
01379     else
01380       aList = theText.split( "\n", QString::SkipEmptyParts );
01381 
01382     if( !aList.isEmpty() )
01383     {
01384       int str_size = aList.first().length();
01385       for( int i = 1, size = aList.count(); i < size; i++ )
01386       {
01387         if ( str_size < (int)aList[i].length() )
01388         {
01389           str_size = aList[i].length();
01390         }
01391       }
01392       theFont = font();
01393       int cur_height = 24;
01394       QCursor* aCursor = QApplication::overrideCursor();
01395       if( aCursor )
01396       {
01397         const QBitmap* aBitmap = aCursor->bitmap();
01398         if( aBitmap )
01399           cur_height = aBitmap->height();
01400       }
01401 
01402       //temp
01403       QSize aSize = QLabel( theText, 0 ).sizeHint();
01404       theTextReg = QRect( thePoint.x(), thePoint.y() + cur_height,
01405                           aSize.width(), aSize.height() );
01406       theRegion = QRect( thePoint.x(), thePoint.y(), 1, 1 );
01407     }
01408   }
01409 }