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.salome-platform.org/ or email : webmaster.salome@opencascade.com
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);
69 GLViewer_ViewPort2d::GLViewer_ViewPort2d( QWidget* parent, GLViewer_ViewFrame* theViewFrame ) :
70 GLViewer_ViewPort( parent ),
71 myMargin( MARGIN ), myWidth( WIDTH ), myHeight( HEIGHT ),
72 myXScale( 1.0 ), myYScale( 1.0 ), myXOldScale( 1.0 ), myYOldScale( 1.0 ),
73 myXPan( 0.0 ), myYPan( 0.0 ),
74 myIsMouseReleaseBlock( false )
76 if( theViewFrame == NULL )
77 myViewFrame = ( GLViewer_ViewFrame* )parent;
79 myViewFrame = theViewFrame;
83 myBorder = new GLViewer_Rect();
85 QBoxLayout* qbl = new QHBoxLayout( this );
86 myGLWidget = new GLViewer_Widget( this, 0 ) ;
87 qbl->addWidget( myGLWidget );
88 myGLWidget->setFocusProxy( this );
89 setMouseTracking( TRUE );
91 myIsDragProcess = noDrag;
92 //myCurDragMousePos = QPoint();
98 myViewPortId = aLastViewPostId;
101 mypFirstPoint = NULL;
104 myObjectTip = new QtxToolTip( myGLWidget );///GLViewer_ObjectTip( this );
105 myObjectTip->setShowDelayTime( 60000 );
106 connect( myObjectTip, SIGNAL( maybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ),
107 this, SLOT( onMaybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ) );
108 // myGLWidget->installEventFilter( myObjectTip );
114 GLViewer_ViewPort2d::~GLViewer_ViewPort2d()
127 SLOT: initializes drag process
129 void GLViewer_ViewPort2d::onStartDragObject( )
131 if( myIsDragProcess == noDrag )
133 myIsDragProcess = initDrag;
134 QCursor::setPos( (int)(*myCurDragPosX), (int)(*myCurDragPosY) );
135 //myCurDragMousePos = QPoint( 0, 0 );
136 delete myCurDragPosX;
137 delete myCurDragPosY;
138 myCurDragPosX = NULL;
139 myCurDragPosY = NULL;
145 SLOT: cuts object to clipboard
147 void GLViewer_ViewPort2d::onCutObject()
149 /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
152 GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
153 aMimeSource->setObject( aMovingObject );
155 QClipboard *aClipboard = QApplication::clipboard();
157 aClipboard->setData( aMimeSource );
159 ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->deleteObject( aMovingObject );
161 GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
162 int aObjNum = aContext->NbSelected();
165 QValueList<GLViewer_Object*> aObjects;
166 GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
167 aContext->InitSelected();
168 for( ; aContext->MoreSelected(); aContext->NextSelected() )
169 aObjects.append( aContext->SelectedObject() );
171 //aMimeSource->setObjects( aObjects ); ouv 6.05.04
173 QClipboard *aClipboard = QApplication::clipboard();
175 aClipboard->setData( aMimeSource );
177 for( int i = 0; i < aObjNum; i++ )
178 aContext->deleteObject( aObjects[i] );
183 SLOT: copies object to clipboard
185 void GLViewer_ViewPort2d::onCopyObject()
187 /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
190 GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
191 aMimeSource->setObject( aMovingObject );
193 QClipboard *aClipboard = QApplication::clipboard();
195 aClipboard->setData( aMimeSource );
198 GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
199 int aObjNum = aContext->NbSelected();
202 QValueList<GLViewer_Object*> aObjects;
203 GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
204 aContext->InitSelected();
205 for( ; aContext->MoreSelected(); aContext->NextSelected() )
206 aObjects.append( aContext->SelectedObject() );
208 //aMimeSource->setObjects( aObjects ); ouv 6.05.04
210 QClipboard *aClipboard = QApplication::clipboard();
212 aClipboard->setData( aMimeSource );
217 SLOT: pastes object from clipboard
219 void GLViewer_ViewPort2d::onPasteObject()
221 /*QClipboard *aClipboard = QApplication::clipboard();
222 QMimeSource* aMimeSource = aClipboard->data();
223 if( aMimeSource->provides( "GLViewer_Object" ) )
230 aType = aMimeSource->format( i );
231 anArray = aMimeSource->encodedData( aType );
232 if( anArray.size() != 0 )
237 if( anArray.size() == 0 )
240 GLViewer_Object* aObject = GLViewer_MimeSource::getObject( anArray, aType );
244 ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->insertObject( aObject, true );
248 QClipboard *aClipboard = QApplication::clipboard();
250 QMimeSource* aMimeSource = aClipboard->data();
251 if( aMimeSource->provides( "GLViewer_Objects" ) )
253 QByteArray anArray = aMimeSource->encodedData( "GLViewer_Objects" );
254 QValueList<GLViewer_Object*> aObjects = GLViewer_MimeSource::getObjects( anArray, "GLViewer_Objects" );
255 if( aObjects.empty() )
257 GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
258 for( int i = 0; i < aObjects.count(); i++ )
259 aContext->insertObject( aObjects[i], true );
265 SLOT: called when object is being dragged
267 void GLViewer_ViewPort2d::onDragObject( QMouseEvent* e )
269 //cout << "---GLViewer_ViewPort2d::onDragObject()---" << endl;
270 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
271 GLViewer_Context* aContext = aViewer->getGLContext();
272 GLViewer_Object* anObject = aContext->getCurrentObject();
277 float aX = e->pos().x();
278 float anY = e->pos().y();
279 aViewer->transPoint( aX, anY );
281 if( myCurDragPosX == NULL && myCurDragPosY == NULL )
283 myCurDragPosX = new float(aX);
284 myCurDragPosY = new float(anY);
288 //QPoint aNewPos = e->pos();
289 //GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
291 if( anObject && (e->state() & LeftButton ) )
293 if( aContext->isSelected( anObject ) )
295 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
297 GLViewer_Object* aMovingObject = aContext->SelectedObject();
299 aMovingObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
303 anObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
305 else if( aContext->NbSelected() && (e->state() & MidButton ) )
306 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
307 (aContext->SelectedObject())->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
309 delete myCurDragPosX;
310 delete myCurDragPosY;
311 myCurDragPosX = new float(aX);
312 myCurDragPosY = new float(anY);
314 myGLWidget->updateGL();
318 Emits 'mouseEvent' signal. [ virtual protected ]
320 void GLViewer_ViewPort2d::mousePressEvent( QMouseEvent* e )
322 emit vpMouseEvent( e );
324 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
325 GLViewer_Context* aContext = aViewer->getGLContext();
327 GLViewer_Object* anObject = NULL;
329 anObject = aContext->getCurrentObject();
331 bool accel = e->state() & GLViewer_ViewTransformer::accelKey();
332 if( ( anObject && !( accel || e->button() == Qt::RightButton ) ) ||
333 ( aContext->NbSelected() && !accel && e->button() == Qt::MidButton ) )
335 myIsDragProcess = inDrag;
340 Emits 'mouseEvent' signal. [ virtual protected ]
342 void GLViewer_ViewPort2d::mouseMoveEvent( QMouseEvent* e )
344 emit vpMouseEvent( e );
346 if( myIsDragProcess == inDrag )
349 /*GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
350 GLViewer_Context* aContext = aViewer->getGLContext();
352 GLViewer_Object* anObj = aContext->getCurrentObject();
353 if( anObj && aContext->currentObjectIsChanged() )
355 //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::add}" << endl;
356 //QToolTip::remove( myGLWidget );
357 QRect* aRect = (aViewer->getWinObjectRect(anObj));
358 //QToolTip::add( myGLWidget, *aRect, anObj->getToolTipText() );
359 myGLWidget->addToolTip( anObj->getToolTipText(), *aRect );
363 //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::remove}" << endl;
364 //QRect* aRect = (aViewer->getWinObjectRect(anObj));
365 //QToolTip::remove( myGLWidget, *aRect );
366 myGLWidget->removeToolTip();
371 Emits 'mouseEvent' signal. [ virtual protected ]
373 void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent* e )
375 if ( myIsMouseReleaseBlock )
377 // skip mouse release after double click
378 myIsMouseReleaseBlock = false;
382 /* show popup menu */
383 if ( e->button() == Qt::RightButton )
385 //QPopupMenu* popup = createPopup();
386 //if ( popup && popup->count() )
387 // popup->exec( QCursor::pos() );
388 //destroyPopup( /*popup*/ );
390 emit vpMouseEvent( e );
392 if( myIsDragProcess == inDrag )
394 bool isAnyMoved = false;
395 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
396 GLViewer_Context* aContext = aViewer->getGLContext();
397 GLViewer_Object* aMovingObject;
398 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
400 aMovingObject = aContext->SelectedObject();
402 isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
405 aMovingObject = aContext->getCurrentObject();
407 isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
409 myIsDragProcess = noDrag;
410 //myCurDragMousePos.setX( 0 );
411 //myCurDragMousePos.setY( 0 );
412 delete myCurDragPosX;
413 delete myCurDragPosY;
414 myCurDragPosX = NULL;
415 myCurDragPosY = NULL;
420 aViewer->updateBorders();
426 Custom mouse double click event handler
428 void GLViewer_ViewPort2d::mouseDoubleClickEvent( QMouseEvent * e )
430 //redefined to block mouse release after mouse double click
431 myIsMouseReleaseBlock = true;
432 // invoke base implementation
433 GLViewer_ViewPort::mouseDoubleClickEvent( e );
437 Creates or deletes compass
438 \param on - if it is true, then to create
440 void GLViewer_ViewPort2d::turnCompass( GLboolean on )
443 myCompass = new GLViewer_Compass( Qt::green, 30, GLViewer_Compass::TopRight, 10, 5, 12, 3 );
449 Creates or deletes grid
450 \param on - if it is true, then to create
452 void GLViewer_ViewPort2d::turnGrid( GLboolean on )
456 myGrid = new GLViewer_Grid( 2*WIDTH, 2*HEIGHT,
458 GRID_XSIZE, GRID_YSIZE,
460 myXScale, myYScale );
468 \param gridColor - new grid color
469 \param axisColor - new axis color
471 void GLViewer_ViewPort2d::setGridColor( const QColor gridColor, const QColor axisColor )
475 myGrid->setGridColor( ( GLfloat )gridColor.red() / 255,
476 ( GLfloat )gridColor.green() / 255,
477 ( GLfloat )gridColor.blue() / 255 );
478 myGrid->setAxisColor( ( GLfloat )axisColor.red() / 255,
479 ( GLfloat )axisColor.green() / 255,
480 ( GLfloat )axisColor.blue() / 255 );
485 Changes background color
486 \param color - new background color
488 void GLViewer_ViewPort2d::setBackgroundColor( const QColor& color )
490 GLViewer_ViewPort::setBackgroundColor( color );
491 myGLWidget->makeCurrent();
492 glClearColor( ( GLfloat )color.red() / 255,
493 ( GLfloat )color.green() / 255,
494 ( GLfloat )color.blue() / 255, 1.0 );
495 myGLWidget->repaint();
499 \return background color
501 QColor GLViewer_ViewPort2d::backgroundColor() const
503 return GLViewer_ViewPort::backgroundColor();
509 void GLViewer_ViewPort2d::initResize( int x, int y )
511 float xa, xb, ya, yb;
512 xa = myBorder->left() - myMargin;
513 xb = myBorder->right() + myMargin;
514 ya = myBorder->top() - myMargin;
515 yb = myBorder->bottom() + myMargin;
517 GLfloat zoom, xzoom, yzoom;
522 xzoom = (GLfloat)x / myWidth;
523 yzoom = (GLfloat)y / myHeight;
525 if ( ( xzoom < yzoom ) && ( xzoom < 1 ) )
527 else if ( ( yzoom < xzoom ) && ( yzoom < 1 ) )
532 zoom = xzoom > yzoom ? xzoom : yzoom;
535 if ( !max && ( ! ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
536 ( ( myXPan - w/2 ) > xa * myXScale * zoom ) ||
537 ( ( myYPan + h/2 ) < yb * myYScale * zoom ) ||
538 ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) )
541 if ( max && ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
542 ( ( myXPan - w/2 ) > xa * myXScale * zoom ) ||
543 ( ( myYPan + h/2 ) < yb * myYScale * zoom ) ||
544 ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) )
554 myGrid->setResize( 2*x, 2*y, zoom );
556 myGLWidget->setScale( myXScale, myYScale, 1.0 );
560 Custom paint event handler
562 void GLViewer_ViewPort2d::paintEvent( QPaintEvent* e )
564 //cout << "GLViewer_ViewPort2d::paintEvent" << endl;
565 myGLWidget->updateGL();
566 GLViewer_ViewPort::paintEvent( e );
570 Custom resize event handler
572 void GLViewer_ViewPort2d::resizeEvent( QResizeEvent* e )
574 //cout << "GLViewer_ViewPort2d::resizeEvent" << endl;
575 GLViewer_ViewPort::resizeEvent( e );
579 Resets view to start state
581 void GLViewer_ViewPort2d::reset()
583 //cout << "GLViewer_ViewPort2d::reset" << endl;
586 GLint vpWidth, vpHeight;
588 myGLWidget->makeCurrent();
589 glGetIntegerv( GL_VIEWPORT, val );
593 GLint w = myGLWidget->getWidth();
594 GLint h = myGLWidget->getHeight();
595 GLfloat zoom = vpWidth / ( GLfloat )w < vpHeight / ( GLfloat )h ?
596 vpWidth / ( GLfloat )w : vpHeight / ( GLfloat )h;
600 myGrid->setPan( 0.0, 0.0 );
601 myGrid->setZoom( zoom / myXScale );
609 myGLWidget->setPan( myXPan, myYPan, 0.0 );
610 myGLWidget->setScale( myXScale, myYScale, 1.0 );
611 myGLWidget->setRotationAngle( 0.0 );
612 myGLWidget->setRotation( 0.0, 0.0, 0.0, 1.0 );
613 myGLWidget->updateGL();
621 void GLViewer_ViewPort2d::pan( int dx, int dy )
623 //cout << "GLViewer_ViewPort2d::pan " << dx << " " << dy << endl;
625 /*myXPan += dx / myXScale;
626 myYPan += dy / myYScale;
628 float ra, rx, ry, rz;
629 myGLWidget->getRotation( ra, rx, ry, rz );
630 GLfloat angle = ra * PI / 180.;
633 myGrid->setPan( myXPan*cos(angle) + myYPan*sin(angle),
634 -myXPan*sin(angle) + myYPan*cos(angle) );
637 float ra, rx, ry, rz;
638 myGLWidget->getRotation( ra, rx, ry, rz );
639 GLfloat angle = ra * PI / 180.;
641 myXPan += (dx*cos(angle) + dy*sin(angle)) / myXScale;
642 myYPan += (-dx*sin(angle) + dy*cos(angle)) / myXScale;
645 myGrid->setPan( myXPan, myYPan );
647 myGLWidget->setPan( myXPan, myYPan, 0.0 );
648 myGLWidget->setScale( myXScale, myYScale, 1.0 );
649 myGLWidget->updateGL();
653 Sets view center in global coords
654 \param x, y - global co-ordinates of center
656 void GLViewer_ViewPort2d::setCenter( int x, int y )
658 //cout << "GLViewer_ViewPort2d::setCenter" << endl;
661 GLint vpWidth, vpHeight;
663 myGLWidget->makeCurrent();
664 glGetIntegerv( GL_VIEWPORT, val );
668 myXPan -= ( x - vpWidth/2 ) / myXScale;
669 myYPan += ( y - vpHeight/2 ) / myYScale;
673 myGrid->setPan( myXPan, myYPan );
674 myGrid->setZoom( myXOldScale / myXScale );
677 myXScale = myXOldScale;
678 myYScale = myYOldScale;
680 myGLWidget->setPan( myXPan, myYPan, 0.0 );
681 myGLWidget->setScale( myXScale, myYScale, 1.0 );
682 myGLWidget->updateGL();
686 Process zoming transformation with mouse tracking from ( x0, y0 ) to ( x1, y1 )
688 void GLViewer_ViewPort2d::zoom( int x0, int y0, int x, int y )
690 //cout << "GLViewer_ViewPort2d::zoom" << endl;
696 if ( dx == 0. && dy == 0. )
699 zm = sqrt(dx * dx + dy * dy) / 100. + 1;
700 zm = (dx > 0.) ? zm : 1. / zm;
710 if( myGrid->setZoom( zm ) )
712 myGLWidget->setPan( myXPan, myYPan, 0.0 );
713 myGLWidget->setScale( myXScale, myYScale, 1.0 );
714 myGLWidget->updateGL();
724 myGLWidget->setPan( myXPan, myYPan, 0.0 );
725 myGLWidget->setScale( myXScale, myYScale, 1.0 );
726 myGLWidget->updateGL();
731 Transforms view by rectangle
732 \param rect - rectangle
734 void GLViewer_ViewPort2d::fitRect( const QRect& rect )
736 float x0, x1, y0, y1;
737 float dx, dy, zm, centerX, centerY;
740 GLint vpWidth, vpHeight;
742 myGLWidget->makeCurrent();
743 glGetIntegerv( GL_VIEWPORT, val );
752 dx = fabs( x1 - x0 );
753 dy = fabs( y1 - y0 );
754 centerX = ( x0 + x1 ) / 2.;
755 centerY = ( y0 + y1 ) / 2.;
757 if ( dx == 0. || dy == 0. )
760 zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy;
762 float aDX = ( vpWidth / 2. - centerX ) / myXScale;
763 float aDY = ( vpHeight / 2. - centerY ) / myYScale;
765 float ra, rx, ry, rz;
766 myGLWidget->getRotation( ra, rx, ry, rz );
767 GLfloat angle = ra * PI / 180.;
769 myXPan += (aDX*cos(angle) - aDY*sin(angle));
770 myYPan -= (aDX*sin(angle) + aDY*cos(angle));
773 myGrid->setPan( myXPan, myYPan );
779 myGrid->setZoom( zm );
781 myGLWidget->setPan( myXPan, myYPan, 0.0 );
782 myGLWidget->setScale( myXScale, myYScale, 1.0 );
783 myGLWidget->updateGL();
787 Transforms view by selection
789 void GLViewer_ViewPort2d::fitSelect()
791 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
792 GLViewer_Context* aContext = aViewer->getGLContext();
797 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
798 aSelRect |= *(aViewer->getWinObjectRect( aContext->SelectedObject() ));
800 if( aSelRect.isValid() )
802 aSelRect.setTop( aSelRect.top() - SELECTION_RECT_GAP );
803 aSelRect.setBottom( aSelRect.bottom() + SELECTION_RECT_GAP );
804 aSelRect.setLeft( aSelRect.left() - SELECTION_RECT_GAP );
805 aSelRect.setRight( aSelRect.right() + SELECTION_RECT_GAP );
811 Transform view by view borders
812 \param keepScale - if it is true, zoom does not change
814 void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
816 //cout << "GLViewer_ViewPort2d::fitAll" << endl;
818 float xa, xb, ya, yb;
820 float xScale, yScale;
822 myMargin = QMAX( myBorder->width(), myBorder->height() ) / 5;
824 xa = myBorder->left() - myMargin;
825 xb = myBorder->right() + myMargin;
826 ya = myBorder->bottom() - myMargin;
827 yb = myBorder->top() + myMargin;
829 float aPoints[8] = { xa, ya, xb, ya, xa, yb, xb, yb };
831 float ra, rx, ry, rz;
832 myGLWidget->getRotation( ra, rx, ry, rz );
833 float angle = ra * PI / 180.;
836 for( i = 0; i < 7; i = i + 2 )
837 rotate_point( aPoints[i], aPoints[i+1], angle );
839 float aBorders[4] = { aPoints[0], aPoints[0], aPoints[1], aPoints[1] };
841 for( i = 2; i < 7; i = i + 2 )
843 if( aBorders[0] < aPoints[i] )
844 aBorders[0] = aPoints[i];
845 if( aBorders[1] > aPoints[i] )
846 aBorders[1] = aPoints[i];
848 if( aBorders[2] < aPoints[i+1] )
849 aBorders[2] = aPoints[i+1];
850 if( aBorders[3] > aPoints[i+1] )
851 aBorders[3] = aPoints[i+1];
855 GLint vpWidth, vpHeight;
857 myGLWidget->makeCurrent();
858 glGetIntegerv( GL_VIEWPORT, val );
862 dx = fabs( aBorders[1] - aBorders[0] );
863 dy = fabs( aBorders[3] - aBorders[2] );
865 myXPan = -( aBorders[0] + aBorders[1] ) / 2;
866 myYPan = -( aBorders[2] + aBorders[3] ) / 2;
871 myXOldScale = myXScale;
872 myYOldScale = myYScale;
878 zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy;
887 myGrid->setPan( myXPan, myYPan );
889 myGrid->setZoom( zm / xScale );
891 myGrid->setZoom( zm / yScale );
894 myGLWidget->setPan( myXPan, myYPan, 0.0 );
895 myGLWidget->setScale( myXScale, myYScale, 1.0 );
896 myGLWidget->updateGL();
899 emit vpUpdateValues();
904 \param x, y - start point
906 void GLViewer_ViewPort2d::startRotation( int x, int y )
908 myGLWidget->setRotationStart( x, y, 1.0 );
913 \param intX, intY - current point
915 void GLViewer_ViewPort2d::rotate( int intX, int intY )
918 GLint vpWidth, vpHeight;
920 myGLWidget->makeCurrent();
921 glGetIntegerv( GL_VIEWPORT, val );
925 float x = intX, y = intY;
926 float x0 = vpWidth/2;
927 float y0 = vpHeight/2;
929 float xs, ys, zs, dx, dy;
930 myGLWidget->getRotationStart( xs, ys, zs );
939 float l1 = pow( double( xs*xs + ys*ys ), 0.5 );
940 float l2 = pow( double( x*x + y*y ), 0.5 );
941 float l = pow( double( dx*dx + dy*dy ), 0.5 );
943 double mult = xs * y - x * ys;
945 if( mult > 0 ) sign = 1;
946 else if( mult < 0 ) sign = -1;
949 float anglePrev = myGLWidget->getRotationAngle();
950 float angleNew = sign * acos( ( l1*l1 + l2*l2 - l*l ) / ( 2 * l1 * l2 )) * 180. / PI;
951 float angle = anglePrev + angleNew;
953 // GLfloat anAngle = angle * PI / 180.; unused
955 float ra, rx, ry, rz;
956 myGLWidget->getRotation( ra, rx, ry, rz );
957 myGLWidget->setRotation( angle, rx, ry, rz );
958 myGLWidget->updateGL();
964 void GLViewer_ViewPort2d::endRotation()
966 float ra, rx, ry, rz;
967 myGLWidget->getRotation( ra, rx, ry, rz );
968 myGLWidget->setRotationAngle( ra );
974 void GLViewer_ViewPort2d::drawCompass()
976 if( !myCompass->getVisible() )
979 GLfloat xScale, yScale, xPan, yPan;
981 int xPos = getWidth();
982 int yPos = getHeight();
984 int cPos = myCompass->getPos();
985 int cSize = myCompass->getSize();
986 QColor cCol = myCompass->getColor();
987 int cWidthTop = myCompass->getArrowWidthTop();
988 int cWidthBot = myCompass->getArrowWidthBottom();
989 int cHeightTop = myCompass->getArrowHeightTop();
990 int cHeightBot = myCompass->getArrowHeightBottom();
992 GLfloat colorR = (cCol.red())/255;
993 GLfloat colorG = (cCol.green())/255;
994 GLfloat colorB = (cCol.blue())/255;
996 float delX = cSize * 0.5;
997 float delY = cSize * 0.5;
999 getScale( xScale, yScale );
1000 getPan( xPan, yPan);
1002 float centerX = (xPos/2 - delX - cSize)/xScale;
1003 float centerY = (yPos/2 - delY - cSize)/yScale;
1007 case GLViewer_Compass::TopLeft:
1010 case GLViewer_Compass::BottomLeft:
1014 case GLViewer_Compass::BottomRight:
1020 float ra, rx, ry, rz;
1021 myGLWidget->getRotation( ra, rx, ry, rz );
1022 GLfloat angle = ra * PI / 180.;
1023 GLfloat /*r = 0.0,*/ x = 0.0 , y = 0.0;
1025 rotate_point( centerX, centerY, -angle );
1030 glColor3f( colorR, colorG, colorB );
1031 glBegin( GL_POLYGON );
1033 x = centerX; y = centerY + cSize / yScale;
1036 x = centerX + cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
1039 x = centerX + cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
1042 x = centerX + cWidthBot / xScale; y = centerY - cSize/yScale;
1045 x = centerX; y = centerY - (cSize - cHeightBot) / yScale ;
1048 x = centerX - cWidthBot / xScale; y = centerY - cSize/yScale;
1051 x = centerX - cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
1054 x = centerX - cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
1058 glEnable( GL_LINE_SMOOTH );
1059 glBegin(GL_LINE_LOOP);
1061 float aCircAngle = 0;
1062 for ( int i = 0; i < 20 * SEGMENTS + 1; i++ )
1064 x = centerX + cos(aCircAngle) * cSize / xScale;
1065 y = centerY + sin(aCircAngle) * cSize / yScale;
1067 aCircAngle += float( STEP ) / 2;
1071 GLdouble modelMatrix[16], projMatrix[16];
1073 GLdouble winxN, winyN, winz;
1074 GLdouble winxE, winyE;
1075 GLdouble winxS, winyS;
1076 GLdouble winxW, winyW;
1079 GLViewer_TexFont* aFont = myCompass->getFont();
1080 float widN = (float)aFont->getStringWidth( "N" );
1081 float widW = (float)aFont->getStringWidth( "W" );
1082 float widS = (float)aFont->getStringWidth( "S" );
1083 float widE = (float)aFont->getStringWidth( "E" );
1084 float heightL = (float)aFont->getStringHeight();
1086 float xGapN = - widN/2 *( 1.0 + sin(angle) );
1087 float xGapS = - widS/2 *( 1.0 - sin(angle) );
1088 float xGapW = - widW/2 *( 1.0 + cos(angle) );
1089 float xGapE = - widE/2 *( 1.0 - cos(angle) );
1091 float yGapN = - heightL/2 *( 1.0 - cos(angle) ) * 0.75;
1092 float yGapS = - heightL/2 *( 1.0 + cos(angle) ) * 0.75;
1093 float yGapW = - heightL/2 *( 1.0 + sin(angle) ) * 0.75;
1094 float yGapE = - heightL/2 *( 1.0 - sin(angle) ) * 0.75;
1096 glGetIntegerv (GL_VIEWPORT, viewport);
1097 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1098 glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1100 gluProject (centerX, centerY + cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxN, &winyN, &winz);
1101 gluProject (centerX + cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxE, &winyE, &winz);
1102 gluProject (centerX, centerY - cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxS, &winyS, &winz);
1103 gluProject (centerX - cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxW, &winyW, &winz);
1105 glColor3f( 1.0, 1.0, 1.0 );
1107 aTextList = glGenLists( 1 );
1108 glNewList( aTextList, GL_COMPILE );
1110 glMatrixMode(GL_PROJECTION);
1113 glOrtho(0,viewport[2],0,viewport[3],-100,100);
1114 glMatrixMode(GL_MODELVIEW);
1118 aFont->drawString( "N", winxN + xGapN, winyN + yGapN );
1119 aFont->drawString( "E", winxE + xGapE, winyE + yGapE );
1120 aFont->drawString( "S", winxS + xGapS, winyS + yGapS );
1121 aFont->drawString( "W", winxW + xGapW, winyW + yGapW );
1123 glMatrixMode(GL_PROJECTION);
1125 glMatrixMode(GL_MODELVIEW);
1130 if ( aTextList != -1 )
1131 glCallList( aTextList );
1135 \return blocking status for current started operations
1137 BlockStatus GLViewer_ViewPort2d::currentBlock()
1139 if( myIsDragProcess == inDrag && myCurDragPosX != NULL && myCurDragPosY != NULL)
1140 return BlockStatus(BS_Highlighting | BS_Selection);
1142 if( mypFirstPoint && mypLastPoint )
1143 return BlockStatus(BS_Highlighting | BS_Selection);
1149 Initializes rectangle selection
1150 \param x, y - start point
1152 void GLViewer_ViewPort2d::startSelectByRect( int x, int y )
1154 if( !mypFirstPoint && !mypLastPoint )
1156 mypFirstPoint = new QPoint( x, y );
1157 mypLastPoint = new QPoint( x, y );
1162 Draws rectangle selection
1163 \param x, y - current point
1165 void GLViewer_ViewPort2d::drawSelectByRect( int x, int y )
1167 if( mypFirstPoint && mypLastPoint )
1170 QPainter p( getPaintDevice() );
1171 p.setPen( Qt::white );
1172 p.setRasterOp( Qt::XorROP );
1174 p.drawRect( selectionRect() ); /* erase */
1176 mypLastPoint->setX( x );
1177 mypLastPoint->setY( y );
1179 p.drawRect( selectionRect() ); /* draw */
1185 Finishes rectangle selection
1187 void GLViewer_ViewPort2d::finishSelectByRect()
1189 if( mypFirstPoint && mypLastPoint )
1192 QPainter p( getPaintDevice() );
1193 p.setPen( Qt::white );
1194 p.setRasterOp( Qt::XorROP );
1196 p.drawRect( selectionRect() ); /* erase */
1198 delete mypFirstPoint;
1199 delete mypLastPoint;
1201 mypFirstPoint = NULL;
1202 mypLastPoint = NULL;
1207 \return rectangle selection
1209 QRect GLViewer_ViewPort2d::selectionRect()
1212 if( mypFirstPoint && mypLastPoint )
1214 aRect.setLeft( QMIN( mypFirstPoint->x(), mypLastPoint->x() ) );
1215 aRect.setTop( QMIN( mypFirstPoint->y(), mypLastPoint->y() ) );
1216 aRect.setRight( QMAX( mypFirstPoint->x(), mypLastPoint->x() ) );
1217 aRect.setBottom( QMAX( mypFirstPoint->y(), mypLastPoint->y() ) );
1225 bool GLViewer_ViewPort2d::startPulling( GLViewer_Pnt point )
1227 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
1228 GLViewer_Context* aContext = aViewer->getGLContext();
1229 ObjList anObjects = aContext->getObjects();
1231 for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
1233 GLViewer_Object* anObject = *it;
1234 GLViewer_Rect aRect = anObject->getPullingRect();
1236 if( aRect.contains( point ) && anObject->startPulling( point ) )
1239 myPullingObject = anObject;
1240 setCursor( *getHandCursor() );
1250 void GLViewer_ViewPort2d::drawPulling( GLViewer_Pnt point )
1252 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
1253 GLViewer_Context* aContext = aViewer->getGLContext();
1254 ObjList anObjects = aContext->getObjects();
1256 GLViewer_Object* aLockedObject = 0;
1257 for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
1259 GLViewer_Object* anObject = *it;
1260 if( !anObject->getVisible() )
1263 GLViewer_Rect aRect = anObject->getPullingRect();
1265 if( aRect.contains( point ) && anObject->portContains( point ) )
1267 aLockedObject = anObject;
1272 myPullingObject->pull( point, aLockedObject );
1277 void GLViewer_ViewPort2d::finishPulling()
1279 myIsPulling = false;
1280 myPullingObject->finishPulling();
1281 setCursor( *getDefaultCursor() );
1285 Convert rectangle in window co-ordinates to GL co-ordinates
1286 \return converted rectangle
1288 GLViewer_Rect GLViewer_ViewPort2d::win2GLV( const QRect& theRect ) const
1290 GLViewer_Rect aRect;
1292 GLdouble modelMatrix[16], projMatrix[16];
1295 GLdouble objx1, objy1;
1296 GLdouble objx2, objy2;
1299 glGetIntegerv (GL_VIEWPORT, viewport);
1300 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1301 glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1303 gluUnProject( theRect.left(), viewport[3] - theRect.top(), 0, modelMatrix, projMatrix, viewport, &objx1, &objy1, &objz );
1304 gluUnProject( theRect.right(), viewport[3] - theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &objx2, &objy2, &objz );
1306 aRect.setLeft( objx1 );
1307 aRect.setTop( objy1 );
1308 aRect.setRight( objx2 );
1309 aRect.setBottom( objy2 );
1315 Convert rectangle in GL co-ordinates to window co-ordinates
1316 \return converted rectangle
1318 QRect GLViewer_ViewPort2d::GLV2win( const GLViewer_Rect& theRect ) const
1322 GLdouble modelMatrix[16], projMatrix[16];
1325 GLdouble winx1, winy1;
1326 GLdouble winx2, winy2;
1329 glGetIntegerv (GL_VIEWPORT, viewport);
1330 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1331 glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1333 gluProject( theRect.left(), theRect.top(), 0, modelMatrix, projMatrix, viewport, &winx1, &winy1, &winz );
1334 gluProject( theRect.right(), theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &winx2, &winy2, &winz );
1336 aRect.setLeft( (int)winx1 );
1337 aRect.setTop( viewport[3] - (int)winy1 );
1338 aRect.setRight( (int)winx2 );
1339 aRect.setBottom( viewport[3] - (int)winy2 );
1345 SLOT: called when tooltip should be shown
1347 void GLViewer_ViewPort2d::onMaybeTip( QPoint thePoint, QString& theText, QFont& theFont, QRect& theTextReg, QRect& theRegion )
1349 GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
1351 GLViewer_Object* anObj = aContext->getCurrentObject();
1354 theText = anObj->getToolTipText();
1355 if( theText.isEmpty() )
1356 theText = anObj->getName();
1359 if( anObj->isTooTipHTML() )
1360 aList = QStringList::split( "<br>", theText );
1362 aList = QStringList::split( "\n", theText );
1364 if( !aList.isEmpty() )
1367 int str_size = aList.first().length();
1368 for( int i = 1, size = aList.count(); i < size; i++ )
1370 if ( str_size < (int)aList[i].length() )
1373 str_size = aList[i].length();
1377 int cur_height = 24;
1378 QCursor* aCursor = QApplication::overrideCursor();
1381 const QBitmap* aBitmap = aCursor->bitmap();
1383 cur_height = aBitmap->height();
1387 QSize aSize = QLabel( theText, 0 ).sizeHint();
1388 theTextReg = QRect( thePoint.x(), thePoint.y() + cur_height,
1389 aSize.width(), aSize.height() );
1390 theRegion = QRect( thePoint.x(), thePoint.y(), 1, 1 );