1 // Copyright (C) 2005 OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
19 // Author : OPEN CASCADE
22 // File: GLViewer_ViewPort2d.cxx
23 // Created: November, 2004
25 /* GLViewer_ViewPort2d Source File */
27 //#include <GLViewerAfx.h>
28 #include "GLViewer_ViewPort2d.h"
29 #include "GLViewer_Viewer2d.h"
30 #include "GLViewer_ViewFrame.h"
31 #include "GLViewer_MimeSource.h"
32 #include "GLViewer_Context.h"
33 #include "GLViewer_Compass.h"
34 #include "GLViewer_Grid.h"
36 #include <QtxToolTip.h>
41 #include <qpopupmenu.h>
43 #include <qapplication.h>
44 #include <qclipboard.h>
53 #define GRID_XSIZE 100
54 #define GRID_YSIZE 100
56 int static aLastViewPostId = 0;
58 void rotate_point( float& theX, float& theY, float theAngle )
60 float aTempX = theX * cos(theAngle) - theY * sin(theAngle);
61 float aTempY = theX * sin(theAngle) + theY * cos(theAngle);
66 GLViewer_ViewPort2d::GLViewer_ViewPort2d( QWidget* parent, GLViewer_ViewFrame* theViewFrame ) :
67 GLViewer_ViewPort( parent ),
68 myMargin( MARGIN ), myWidth( WIDTH ), myHeight( HEIGHT ),
69 myXScale( 1.0 ), myYScale( 1.0 ), myXOldScale( 1.0 ), myYOldScale( 1.0 ),
70 myXPan( 0.0 ), myYPan( 0.0 ),
71 myIsMouseReleaseBlock( false )
73 if( theViewFrame == NULL )
74 myViewFrame = ( GLViewer_ViewFrame* )parent;
76 myViewFrame = theViewFrame;
80 myBorder = new GLViewer_Rect();
82 QBoxLayout* qbl = new QHBoxLayout( this );
83 myGLWidget = new GLViewer_Widget( this, 0 ) ;
84 qbl->addWidget( myGLWidget );
85 myGLWidget->setFocusProxy( this );
86 setMouseTracking( TRUE );
88 myIsDragProcess = noDrag;
89 //myCurDragMousePos = QPoint();
95 myViewPortId = aLastViewPostId;
101 myObjectTip = new QtxToolTip( myGLWidget );///GLViewer_ObjectTip( this );
102 myObjectTip->setShowDelayTime( 60000 );
103 connect( myObjectTip, SIGNAL( maybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ),
104 this, SLOT( onMaybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ) );
105 // myGLWidget->installEventFilter( myObjectTip );
108 GLViewer_ViewPort2d::~GLViewer_ViewPort2d()
120 void GLViewer_ViewPort2d::onStartDragObject( )
122 if( myIsDragProcess == noDrag )
124 myIsDragProcess = initDrag;
125 QCursor::setPos( (int)(*myCurDragPosX), (int)(*myCurDragPosY) );
126 //myCurDragMousePos = QPoint( 0, 0 );
127 delete myCurDragPosX;
128 delete myCurDragPosY;
129 myCurDragPosX = NULL;
130 myCurDragPosY = NULL;
135 void GLViewer_ViewPort2d::onCutObject()
137 /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
140 GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
141 aMimeSource->setObject( aMovingObject );
143 QClipboard *aClipboard = QApplication::clipboard();
145 aClipboard->setData( aMimeSource );
147 ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->deleteObject( aMovingObject );
149 GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
150 int aObjNum = aContext->NbSelected();
153 QValueList<GLViewer_Object*> aObjects;
154 GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
155 aContext->InitSelected();
156 for( ; aContext->MoreSelected(); aContext->NextSelected() )
157 aObjects.append( aContext->SelectedObject() );
159 //aMimeSource->setObjects( aObjects ); ouv 6.05.04
161 QClipboard *aClipboard = QApplication::clipboard();
163 aClipboard->setData( aMimeSource );
165 for( int i = 0; i < aObjNum; i++ )
166 aContext->deleteObject( aObjects[i] );
170 void GLViewer_ViewPort2d::onCopyObject()
172 /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
175 GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
176 aMimeSource->setObject( aMovingObject );
178 QClipboard *aClipboard = QApplication::clipboard();
180 aClipboard->setData( aMimeSource );
183 GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
184 int aObjNum = aContext->NbSelected();
187 QValueList<GLViewer_Object*> aObjects;
188 GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
189 aContext->InitSelected();
190 for( ; aContext->MoreSelected(); aContext->NextSelected() )
191 aObjects.append( aContext->SelectedObject() );
193 //aMimeSource->setObjects( aObjects ); ouv 6.05.04
195 QClipboard *aClipboard = QApplication::clipboard();
197 aClipboard->setData( aMimeSource );
201 void GLViewer_ViewPort2d::onPasteObject()
203 /*QClipboard *aClipboard = QApplication::clipboard();
204 QMimeSource* aMimeSource = aClipboard->data();
205 if( aMimeSource->provides( "GLViewer_Object" ) )
212 aType = aMimeSource->format( i );
213 anArray = aMimeSource->encodedData( aType );
214 if( anArray.size() != 0 )
219 if( anArray.size() == 0 )
222 GLViewer_Object* aObject = GLViewer_MimeSource::getObject( anArray, aType );
226 ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->insertObject( aObject, true );
230 QClipboard *aClipboard = QApplication::clipboard();
232 QMimeSource* aMimeSource = aClipboard->data();
233 if( aMimeSource->provides( "GLViewer_Objects" ) )
235 QByteArray anArray = aMimeSource->encodedData( "GLViewer_Objects" );
236 QValueList<GLViewer_Object*> aObjects = GLViewer_MimeSource::getObjects( anArray, "GLViewer_Objects" );
237 if( aObjects.empty() )
239 GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
240 for( int i = 0; i < aObjects.count(); i++ )
241 aContext->insertObject( aObjects[i], true );
246 void GLViewer_ViewPort2d::onDragObject( QMouseEvent* e )
248 //cout << "---GLViewer_ViewPort2d::onDragObject()---" << endl;
249 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
250 GLViewer_Context* aContext = aViewer->getGLContext();
251 GLViewer_Object* anObject = aContext->getCurrentObject();
256 float aX = e->pos().x();
257 float anY = e->pos().y();
258 aViewer->transPoint( aX, anY );
260 if( myCurDragPosX == NULL && myCurDragPosY == NULL )
262 myCurDragPosX = new float(aX);
263 myCurDragPosY = new float(anY);
267 //QPoint aNewPos = e->pos();
268 //GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
270 if( anObject && (e->state() & LeftButton ) )
272 if( aContext->isSelected( anObject ) )
274 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
276 GLViewer_Object* aMovingObject = aContext->SelectedObject();
278 aMovingObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
282 anObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
284 else if( aContext->NbSelected() && (e->state() & MidButton ) )
285 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
286 (aContext->SelectedObject())->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
288 delete myCurDragPosX;
289 delete myCurDragPosY;
290 myCurDragPosX = new float(aX);
291 myCurDragPosY = new float(anY);
293 myGLWidget->updateGL();
297 Emits 'mouseEvent' signal. [ virtual protected ]
299 void GLViewer_ViewPort2d::mousePressEvent( QMouseEvent* e )
301 emit vpMouseEvent( e );
303 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
304 GLViewer_Context* aContext = aViewer->getGLContext();
306 GLViewer_Object* anObject = NULL;
308 anObject = aContext->getCurrentObject();
310 bool accel = e->state() & GLViewer_ViewTransformer::accelKey();
311 if( ( anObject && !( accel || e->button() == Qt::RightButton ) ) ||
312 ( aContext->NbSelected() && !accel && e->button() == Qt::MidButton ) )
314 myIsDragProcess = inDrag;
319 Emits 'mouseEvent' signal. [ virtual protected ]
321 void GLViewer_ViewPort2d::mouseMoveEvent( QMouseEvent* e )
323 emit vpMouseEvent( e );
325 if( myIsDragProcess == inDrag )
328 /*GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
329 GLViewer_Context* aContext = aViewer->getGLContext();
331 GLViewer_Object* anObj = aContext->getCurrentObject();
332 if( anObj && aContext->currentObjectIsChanged() )
334 //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::add}" << endl;
335 //QToolTip::remove( myGLWidget );
336 QRect* aRect = (aViewer->getWinObjectRect(anObj));
337 //QToolTip::add( myGLWidget, *aRect, anObj->getToolTipText() );
338 myGLWidget->addToolTip( anObj->getToolTipText(), *aRect );
342 //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::remove}" << endl;
343 //QRect* aRect = (aViewer->getWinObjectRect(anObj));
344 //QToolTip::remove( myGLWidget, *aRect );
345 myGLWidget->removeToolTip();
350 Emits 'mouseEvent' signal. [ virtual protected ]
352 void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent* e )
354 if ( myIsMouseReleaseBlock )
356 // skip mouse release after double click
357 myIsMouseReleaseBlock = false;
361 /* show popup menu */
362 if ( e->button() == Qt::RightButton )
364 //QPopupMenu* popup = createPopup();
365 //if ( popup && popup->count() )
366 // popup->exec( QCursor::pos() );
367 //destroyPopup( /*popup*/ );
369 emit vpMouseEvent( e );
371 if( myIsDragProcess == inDrag )
373 bool isAnyMoved = false;
374 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
375 GLViewer_Context* aContext = aViewer->getGLContext();
376 GLViewer_Object* aMovingObject;
377 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
379 aMovingObject = aContext->SelectedObject();
381 isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
384 aMovingObject = aContext->getCurrentObject();
386 isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
388 myIsDragProcess = noDrag;
389 //myCurDragMousePos.setX( 0 );
390 //myCurDragMousePos.setY( 0 );
391 delete myCurDragPosX;
392 delete myCurDragPosY;
393 myCurDragPosX = NULL;
394 myCurDragPosY = NULL;
399 aViewer->updateBorders();
404 void GLViewer_ViewPort2d::mouseDoubleClickEvent( QMouseEvent * e )
406 //redefined to block mouse release after mouse double click
407 myIsMouseReleaseBlock = true;
408 // invoke base implementation
409 GLViewer_ViewPort::mouseDoubleClickEvent( e );
412 void GLViewer_ViewPort2d::turnCompass( GLboolean on )
415 myCompass = new GLViewer_Compass( Qt::green, 30, GLViewer_Compass::TopRight, 10, 5, 12, 3 );
420 void GLViewer_ViewPort2d::turnGrid( GLboolean on )
424 myGrid = new GLViewer_Grid( 2*WIDTH, 2*HEIGHT,
426 GRID_XSIZE, GRID_YSIZE,
428 myXScale, myYScale );
434 void GLViewer_ViewPort2d::setGridColor( const QColor gridColor, const QColor axisColor )
438 myGrid->setGridColor( ( GLfloat )gridColor.red() / 255,
439 ( GLfloat )gridColor.green() / 255,
440 ( GLfloat )gridColor.blue() / 255 );
441 myGrid->setAxisColor( ( GLfloat )axisColor.red() / 255,
442 ( GLfloat )axisColor.green() / 255,
443 ( GLfloat )axisColor.blue() / 255 );
447 void GLViewer_ViewPort2d::setBackgroundColor( const QColor& color )
449 GLViewer_ViewPort::setBackgroundColor( color );
450 myGLWidget->makeCurrent();
451 glClearColor( ( GLfloat )color.red() / 255,
452 ( GLfloat )color.green() / 255,
453 ( GLfloat )color.blue() / 255, 1.0 );
454 myGLWidget->repaint();
457 QColor GLViewer_ViewPort2d::backgroundColor() const
459 return GLViewer_ViewPort::backgroundColor();
462 void GLViewer_ViewPort2d::initResize( int x, int y )
464 float xa, xb, ya, yb;
465 xa = myBorder->left() - myMargin;
466 xb = myBorder->right() + myMargin;
467 ya = myBorder->top() - myMargin;
468 yb = myBorder->bottom() + myMargin;
470 GLfloat zoom, xzoom, yzoom;
475 xzoom = (GLfloat)x / myWidth;
476 yzoom = (GLfloat)y / myHeight;
478 if ( ( xzoom < yzoom ) && ( xzoom < 1 ) )
480 else if ( ( yzoom < xzoom ) && ( yzoom < 1 ) )
485 zoom = xzoom > yzoom ? xzoom : yzoom;
488 if ( !max && ( ! ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
489 ( ( myXPan - w/2 ) > xa * myXScale * zoom ) ||
490 ( ( myYPan + h/2 ) < yb * myYScale * zoom ) ||
491 ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) )
494 if ( max && ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
495 ( ( myXPan - w/2 ) > xa * myXScale * zoom ) ||
496 ( ( myYPan + h/2 ) < yb * myYScale * zoom ) ||
497 ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) )
507 myGrid->setResize( 2*x, 2*y, zoom );
509 myGLWidget->setScale( myXScale, myYScale, 1.0 );
512 void GLViewer_ViewPort2d::paintEvent( QPaintEvent* e )
514 //cout << "GLViewer_ViewPort2d::paintEvent" << endl;
515 myGLWidget->updateGL();
516 GLViewer_ViewPort::paintEvent( e );
519 void GLViewer_ViewPort2d::resizeEvent( QResizeEvent* e )
521 //cout << "GLViewer_ViewPort2d::resizeEvent" << endl;
522 GLViewer_ViewPort::resizeEvent( e );
525 void GLViewer_ViewPort2d::reset()
527 //cout << "GLViewer_ViewPort2d::reset" << endl;
530 GLint vpWidth, vpHeight;
532 myGLWidget->makeCurrent();
533 glGetIntegerv( GL_VIEWPORT, val );
537 GLint w = myGLWidget->getWidth();
538 GLint h = myGLWidget->getHeight();
539 GLfloat zoom = vpWidth / ( GLfloat )w < vpHeight / ( GLfloat )h ?
540 vpWidth / ( GLfloat )w : vpHeight / ( GLfloat )h;
544 myGrid->setPan( 0.0, 0.0 );
545 myGrid->setZoom( zoom / myXScale );
553 myGLWidget->setPan( myXPan, myYPan, 0.0 );
554 myGLWidget->setScale( myXScale, myYScale, 1.0 );
555 myGLWidget->setRotationAngle( 0.0 );
556 myGLWidget->setRotation( 0.0, 0.0, 0.0, 1.0 );
557 myGLWidget->updateGL();
560 void GLViewer_ViewPort2d::pan( int dx, int dy )
562 //cout << "GLViewer_ViewPort2d::pan " << dx << " " << dy << endl;
564 /*myXPan += dx / myXScale;
565 myYPan += dy / myYScale;
567 float ra, rx, ry, rz;
568 myGLWidget->getRotation( ra, rx, ry, rz );
569 GLfloat angle = ra * PI / 180.;
572 myGrid->setPan( myXPan*cos(angle) + myYPan*sin(angle),
573 -myXPan*sin(angle) + myYPan*cos(angle) );
576 float ra, rx, ry, rz;
577 myGLWidget->getRotation( ra, rx, ry, rz );
578 GLfloat angle = ra * PI / 180.;
580 myXPan += (dx*cos(angle) + dy*sin(angle)) / myXScale;
581 myYPan += (-dx*sin(angle) + dy*cos(angle)) / myXScale;
584 myGrid->setPan( myXPan, myYPan );
586 myGLWidget->setPan( myXPan, myYPan, 0.0 );
587 myGLWidget->setScale( myXScale, myYScale, 1.0 );
588 myGLWidget->updateGL();
591 void GLViewer_ViewPort2d::setCenter( int x, int y )
593 //cout << "GLViewer_ViewPort2d::setCenter" << endl;
596 GLint vpWidth, vpHeight;
598 myGLWidget->makeCurrent();
599 glGetIntegerv( GL_VIEWPORT, val );
603 myXPan -= ( x - vpWidth/2 ) / myXScale;
604 myYPan += ( y - vpHeight/2 ) / myYScale;
608 myGrid->setPan( myXPan, myYPan );
609 myGrid->setZoom( myXOldScale / myXScale );
612 myXScale = myXOldScale;
613 myYScale = myYOldScale;
615 myGLWidget->setPan( myXPan, myYPan, 0.0 );
616 myGLWidget->setScale( myXScale, myYScale, 1.0 );
617 myGLWidget->updateGL();
620 void GLViewer_ViewPort2d::zoom( int x0, int y0, int x, int y )
622 //cout << "GLViewer_ViewPort2d::zoom" << endl;
628 if ( dx == 0. && dy == 0. )
631 zm = sqrt(dx * dx + dy * dy) / 100. + 1;
632 zm = (dx > 0.) ? zm : 1. / zm;
642 if( myGrid->setZoom( zm ) )
644 myGLWidget->setPan( myXPan, myYPan, 0.0 );
645 myGLWidget->setScale( myXScale, myYScale, 1.0 );
646 myGLWidget->updateGL();
656 myGLWidget->setPan( myXPan, myYPan, 0.0 );
657 myGLWidget->setScale( myXScale, myYScale, 1.0 );
658 myGLWidget->updateGL();
662 void GLViewer_ViewPort2d::fitRect( const QRect& rect )
664 float x0, x1, y0, y1;
665 float dx, dy, zm, centerX, centerY;
668 GLint vpWidth, vpHeight;
670 myGLWidget->makeCurrent();
671 glGetIntegerv( GL_VIEWPORT, val );
680 dx = fabs( x1 - x0 );
681 dy = fabs( y1 - y0 );
682 centerX = ( x0 + x1 ) / 2.;
683 centerY = ( y0 + y1 ) / 2.;
685 if ( dx == 0. || dy == 0. )
688 zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy;
690 float aDX = ( vpWidth / 2. - centerX ) / myXScale;
691 float aDY = ( vpHeight / 2. - centerY ) / myYScale;
693 float ra, rx, ry, rz;
694 myGLWidget->getRotation( ra, rx, ry, rz );
695 GLfloat angle = ra * PI / 180.;
697 myXPan += (aDX*cos(angle) - aDY*sin(angle));
698 myYPan -= (aDX*sin(angle) + aDY*cos(angle));
701 myGrid->setPan( myXPan, myYPan );
707 myGrid->setZoom( zm );
709 myGLWidget->setPan( myXPan, myYPan, 0.0 );
710 myGLWidget->setScale( myXScale, myYScale, 1.0 );
711 myGLWidget->updateGL();
714 void GLViewer_ViewPort2d::fitSelect()
716 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
717 GLViewer_Context* aContext = aViewer->getGLContext();
722 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
723 aSelRect |= *(aViewer->getWinObjectRect( aContext->SelectedObject() ));
725 if( aSelRect.isValid() )
727 aSelRect.setTop( aSelRect.top() - SELECTION_RECT_GAP );
728 aSelRect.setBottom( aSelRect.bottom() + SELECTION_RECT_GAP );
729 aSelRect.setLeft( aSelRect.left() - SELECTION_RECT_GAP );
730 aSelRect.setRight( aSelRect.right() + SELECTION_RECT_GAP );
735 void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
737 //cout << "GLViewer_ViewPort2d::fitAll" << endl;
739 float xa, xb, ya, yb;
741 float xScale, yScale;
743 myMargin = QMAX( myBorder->width(), myBorder->height() ) / 5;
745 xa = myBorder->left() - myMargin;
746 xb = myBorder->right() + myMargin;
747 ya = myBorder->bottom() - myMargin;
748 yb = myBorder->top() + myMargin;
750 float aPoints[8] = { xa, ya, xb, ya, xa, yb, xb, yb };
752 float ra, rx, ry, rz;
753 myGLWidget->getRotation( ra, rx, ry, rz );
754 float angle = ra * PI / 180.;
757 for( i = 0; i < 7; i = i + 2 )
758 rotate_point( aPoints[i], aPoints[i+1], angle );
760 float aBorders[4] = { aPoints[0], aPoints[0], aPoints[1], aPoints[1] };
762 for( i = 2; i < 7; i = i + 2 )
764 if( aBorders[0] < aPoints[i] )
765 aBorders[0] = aPoints[i];
766 if( aBorders[1] > aPoints[i] )
767 aBorders[1] = aPoints[i];
769 if( aBorders[2] < aPoints[i+1] )
770 aBorders[2] = aPoints[i+1];
771 if( aBorders[3] > aPoints[i+1] )
772 aBorders[3] = aPoints[i+1];
776 GLint vpWidth, vpHeight;
778 myGLWidget->makeCurrent();
779 glGetIntegerv( GL_VIEWPORT, val );
783 dx = fabs( aBorders[1] - aBorders[0] );
784 dy = fabs( aBorders[3] - aBorders[2] );
786 myXPan = -( aBorders[0] + aBorders[1] ) / 2;
787 myYPan = -( aBorders[2] + aBorders[3] ) / 2;
792 myXOldScale = myXScale;
793 myYOldScale = myYScale;
799 zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy;
808 myGrid->setPan( myXPan, myYPan );
810 myGrid->setZoom( zm / xScale );
812 myGrid->setZoom( zm / yScale );
815 myGLWidget->setPan( myXPan, myYPan, 0.0 );
816 myGLWidget->setScale( myXScale, myYScale, 1.0 );
817 myGLWidget->updateGL();
820 emit vpUpdateValues();
823 void GLViewer_ViewPort2d::startRotation( int x, int y )
825 myGLWidget->setRotationStart( x, y, 1.0 );
828 void GLViewer_ViewPort2d::rotate( int intX, int intY )
831 GLint vpWidth, vpHeight;
833 myGLWidget->makeCurrent();
834 glGetIntegerv( GL_VIEWPORT, val );
838 float x = intX, y = intY;
839 float x0 = vpWidth/2;
840 float y0 = vpHeight/2;
842 float xs, ys, zs, dx, dy;
843 myGLWidget->getRotationStart( xs, ys, zs );
852 float l1 = pow( double( xs*xs + ys*ys ), 0.5 );
853 float l2 = pow( double( x*x + y*y ), 0.5 );
854 float l = pow( double( dx*dx + dy*dy ), 0.5 );
856 double mult = xs * y - x * ys;
858 if( mult > 0 ) sign = 1;
859 else if( mult < 0 ) sign = -1;
862 float anglePrev = myGLWidget->getRotationAngle();
863 float angleNew = sign * acos( ( l1*l1 + l2*l2 - l*l ) / ( 2 * l1 * l2 )) * 180. / PI;
864 float angle = anglePrev + angleNew;
866 // GLfloat anAngle = angle * PI / 180.; unused
868 float ra, rx, ry, rz;
869 myGLWidget->getRotation( ra, rx, ry, rz );
870 myGLWidget->setRotation( angle, rx, ry, rz );
871 myGLWidget->updateGL();
874 void GLViewer_ViewPort2d::endRotation()
876 float ra, rx, ry, rz;
877 myGLWidget->getRotation( ra, rx, ry, rz );
878 myGLWidget->setRotationAngle( ra );
881 void GLViewer_ViewPort2d::drawCompass()
883 if( !myCompass->getVisible() )
886 GLfloat xScale, yScale, xPan, yPan;
888 int xPos = getWidth();
889 int yPos = getHeight();
891 int cPos = myCompass->getPos();
892 int cSize = myCompass->getSize();
893 QColor cCol = myCompass->getColor();
894 int cWidthTop = myCompass->getArrowWidthTop();
895 int cWidthBot = myCompass->getArrowWidthBottom();
896 int cHeightTop = myCompass->getArrowHeightTop();
897 int cHeightBot = myCompass->getArrowHeightBottom();
899 GLfloat colorR = (cCol.red())/255;
900 GLfloat colorG = (cCol.green())/255;
901 GLfloat colorB = (cCol.blue())/255;
903 float delX = cSize * 0.5;
904 float delY = cSize * 0.5;
906 getScale( xScale, yScale );
909 float centerX = (xPos/2 - delX - cSize)/xScale;
910 float centerY = (yPos/2 - delY - cSize)/yScale;
914 case GLViewer_Compass::TopLeft:
917 case GLViewer_Compass::BottomLeft:
921 case GLViewer_Compass::BottomRight:
927 float ra, rx, ry, rz;
928 myGLWidget->getRotation( ra, rx, ry, rz );
929 GLfloat angle = ra * PI / 180.;
930 GLfloat /*r = 0.0,*/ x = 0.0 , y = 0.0;
932 rotate_point( centerX, centerY, -angle );
937 glColor3f( colorR, colorG, colorB );
938 glBegin( GL_POLYGON );
940 x = centerX; y = centerY + cSize / yScale;
943 x = centerX + cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
946 x = centerX + cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
949 x = centerX + cWidthBot / xScale; y = centerY - cSize/yScale;
952 x = centerX; y = centerY - (cSize - cHeightBot) / yScale ;
955 x = centerX - cWidthBot / xScale; y = centerY - cSize/yScale;
958 x = centerX - cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
961 x = centerX - cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
965 glEnable( GL_LINE_SMOOTH );
966 glBegin(GL_LINE_LOOP);
968 float aCircAngle = 0;
969 for ( int i = 0; i < 20 * SEGMENTS + 1; i++ )
971 x = centerX + cos(aCircAngle) * cSize / xScale;
972 y = centerY + sin(aCircAngle) * cSize / yScale;
974 aCircAngle += float( STEP ) / 2;
978 GLdouble modelMatrix[16], projMatrix[16];
980 GLdouble winxN, winyN, winz;
981 GLdouble winxE, winyE;
982 GLdouble winxS, winyS;
983 GLdouble winxW, winyW;
986 GLViewer_TexFont* aFont = myCompass->getFont();
987 float widN = (float)aFont->getStringWidth( "N" );
988 float widW = (float)aFont->getStringWidth( "W" );
989 float widS = (float)aFont->getStringWidth( "S" );
990 float widE = (float)aFont->getStringWidth( "E" );
991 float heightL = (float)aFont->getStringHeight();
993 float xGapN = - widN/2 *( 1.0 + sin(angle) );
994 float xGapS = - widS/2 *( 1.0 - sin(angle) );
995 float xGapW = - widW/2 *( 1.0 + cos(angle) );
996 float xGapE = - widE/2 *( 1.0 - cos(angle) );
998 float yGapN = - heightL/2 *( 1.0 - cos(angle) ) * 0.75;
999 float yGapS = - heightL/2 *( 1.0 + cos(angle) ) * 0.75;
1000 float yGapW = - heightL/2 *( 1.0 + sin(angle) ) * 0.75;
1001 float yGapE = - heightL/2 *( 1.0 - sin(angle) ) * 0.75;
1003 glGetIntegerv (GL_VIEWPORT, viewport);
1004 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1005 glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1007 gluProject (centerX, centerY + cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxN, &winyN, &winz);
1008 gluProject (centerX + cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxE, &winyE, &winz);
1009 gluProject (centerX, centerY - cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxS, &winyS, &winz);
1010 gluProject (centerX - cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxW, &winyW, &winz);
1012 glColor3f( 1.0, 1.0, 1.0 );
1014 aTextList = glGenLists( 1 );
1015 glNewList( aTextList, GL_COMPILE );
1017 glMatrixMode(GL_PROJECTION);
1020 glOrtho(0,viewport[2],0,viewport[3],-100,100);
1021 glMatrixMode(GL_MODELVIEW);
1025 aFont->drawString( "N", winxN + xGapN, winyN + yGapN );
1026 aFont->drawString( "E", winxE + xGapE, winyE + yGapE );
1027 aFont->drawString( "S", winxS + xGapS, winyS + yGapS );
1028 aFont->drawString( "W", winxW + xGapW, winyW + yGapW );
1030 glMatrixMode(GL_PROJECTION);
1032 glMatrixMode(GL_MODELVIEW);
1037 if ( aTextList != -1 )
1038 glCallList( aTextList );
1041 BlockStatus GLViewer_ViewPort2d::currentBlock()
1043 if( myIsDragProcess == inDrag && myCurDragPosX != NULL && myCurDragPosY != NULL)
1044 return BlockStatus(BS_Highlighting | BS_Selection);
1046 if( mypFirstPoint && mypLastPoint )
1047 return BlockStatus(BS_Highlighting | BS_Selection);
1052 void GLViewer_ViewPort2d::startSelectByRect( int x, int y )
1054 if( !mypFirstPoint && !mypLastPoint )
1056 mypFirstPoint = new QPoint( x, y );
1057 mypLastPoint = new QPoint( x, y );
1060 void GLViewer_ViewPort2d::drawSelectByRect( int x, int y )
1062 if( mypFirstPoint && mypLastPoint )
1065 QPainter p( getPaintDevice() );
1066 p.setPen( Qt::white );
1067 p.setRasterOp( Qt::XorROP );
1069 p.drawRect( selectionRect() ); /* erase */
1071 mypLastPoint->setX( x );
1072 mypLastPoint->setY( y );
1074 p.drawRect( selectionRect() ); /* draw */
1078 void GLViewer_ViewPort2d::finishSelectByRect()
1080 if( mypFirstPoint && mypLastPoint )
1083 QPainter p( getPaintDevice() );
1084 p.setPen( Qt::white );
1085 p.setRasterOp( Qt::XorROP );
1087 p.drawRect( selectionRect() ); /* erase */
1089 delete mypFirstPoint;
1090 delete mypLastPoint;
1092 mypFirstPoint = NULL;
1093 mypLastPoint = NULL;
1097 QRect GLViewer_ViewPort2d::selectionRect()
1100 if( mypFirstPoint && mypLastPoint )
1102 aRect.setLeft( QMIN( mypFirstPoint->x(), mypLastPoint->x() ) );
1103 aRect.setTop( QMIN( mypFirstPoint->y(), mypLastPoint->y() ) );
1104 aRect.setRight( QMAX( mypFirstPoint->x(), mypLastPoint->x() ) );
1105 aRect.setBottom( QMAX( mypFirstPoint->y(), mypLastPoint->y() ) );
1111 bool GLViewer_ViewPort2d::startPulling( GLViewer_Pnt point )
1113 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
1114 GLViewer_Context* aContext = aViewer->getGLContext();
1115 ObjList anObjects = aContext->getObjects();
1117 for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
1119 GLViewer_Object* anObject = *it;
1120 GLViewer_Rect aRect = anObject->getPullingRect();
1122 if( aRect.contains( point ) && anObject->startPulling( point ) )
1125 myPullingObject = anObject;
1126 setCursor( *getHandCursor() );
1134 void GLViewer_ViewPort2d::drawPulling( GLViewer_Pnt point )
1136 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
1137 GLViewer_Context* aContext = aViewer->getGLContext();
1138 ObjList anObjects = aContext->getObjects();
1140 GLViewer_Object* aLockedObject = 0;
1141 for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
1143 GLViewer_Object* anObject = *it;
1144 if( !anObject->getVisible() )
1147 GLViewer_Rect aRect = anObject->getPullingRect();
1149 if( aRect.contains( point ) && anObject->portContains( point ) )
1151 aLockedObject = anObject;
1156 myPullingObject->pull( point, aLockedObject );
1159 void GLViewer_ViewPort2d::finishPulling()
1161 myIsPulling = false;
1162 myPullingObject->finishPulling();
1163 setCursor( *getDefaultCursor() );
1166 GLViewer_Rect GLViewer_ViewPort2d::win2GLV( const QRect& theRect ) const
1168 GLViewer_Rect aRect;
1170 GLdouble modelMatrix[16], projMatrix[16];
1173 GLdouble objx1, objy1;
1174 GLdouble objx2, objy2;
1177 glGetIntegerv (GL_VIEWPORT, viewport);
1178 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1179 glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1181 gluUnProject( theRect.left(), viewport[3] - theRect.top(), 0, modelMatrix, projMatrix, viewport, &objx1, &objy1, &objz );
1182 gluUnProject( theRect.right(), viewport[3] - theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &objx2, &objy2, &objz );
1184 aRect.setLeft( objx1 );
1185 aRect.setTop( objy1 );
1186 aRect.setRight( objx2 );
1187 aRect.setBottom( objy2 );
1192 QRect GLViewer_ViewPort2d::GLV2win( const GLViewer_Rect& theRect ) const
1196 GLdouble modelMatrix[16], projMatrix[16];
1199 GLdouble winx1, winy1;
1200 GLdouble winx2, winy2;
1203 glGetIntegerv (GL_VIEWPORT, viewport);
1204 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1205 glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1207 gluProject( theRect.left(), theRect.top(), 0, modelMatrix, projMatrix, viewport, &winx1, &winy1, &winz );
1208 gluProject( theRect.right(), theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &winx2, &winy2, &winz );
1210 aRect.setLeft( (int)winx1 );
1211 aRect.setTop( viewport[3] - (int)winy1 );
1212 aRect.setRight( (int)winx2 );
1213 aRect.setBottom( viewport[3] - (int)winy2 );
1218 void GLViewer_ViewPort2d::onMaybeTip( QPoint thePoint, QString& theText, QFont& theFont, QRect& theTextReg, QRect& theRegion )
1220 GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
1222 GLViewer_Object* anObj = aContext->getCurrentObject();
1225 theText = anObj->getToolTipText();
1226 if( theText.isEmpty() )
1227 theText = anObj->getName();
1230 if( anObj->isTooTipHTML() )
1231 aList = QStringList::split( "<br>", theText );
1233 aList = QStringList::split( "\n", theText );
1235 if( !aList.isEmpty() )
1238 int str_size = aList.first().length();
1239 for( int i = 1, size = aList.count(); i < size; i++ )
1241 if( str_size < aList[i].length() )
1244 str_size = aList[i].length();
1248 int cur_height = 24;
1249 QCursor* aCursor = QApplication::overrideCursor();
1252 const QBitmap* aBitmap = aCursor->bitmap();
1254 cur_height = aBitmap->height();
1258 QSize aSize = QLabel( theText, 0 ).sizeHint();
1259 theTextReg = QRect( thePoint.x(), thePoint.y() + cur_height,
1260 aSize.width(), aSize.height() );
1261 theRegion = QRect( thePoint.x(), thePoint.y(), 1, 1 );