1 // File: GLViewer_ViewPort2d.cxx
2 // Created: November, 2004
4 // Copyright (C) CEA 2004
6 /* GLViewer_ViewPort2d Source File */
8 //#include <GLViewerAfx.h>
9 #include "GLViewer_ViewPort2d.h"
10 #include "GLViewer_Viewer2d.h"
11 #include "GLViewer_ViewFrame.h"
12 #include "GLViewer_MimeSource.h"
13 #include "GLViewer_Context.h"
14 #include "GLViewer_Compass.h"
15 #include "GLViewer_Grid.h"
17 #include <QtxToolTip.h>
22 #include <qpopupmenu.h>
24 #include <qapplication.h>
25 #include <qclipboard.h>
34 #define GRID_XSIZE 100
35 #define GRID_YSIZE 100
37 int static aLastViewPostId = 0;
39 void rotate_point( float& theX, float& theY, float theAngle )
41 float aTempX = theX * cos(theAngle) - theY * sin(theAngle);
42 float aTempY = theX * sin(theAngle) + theY * cos(theAngle);
47 GLViewer_ViewPort2d::GLViewer_ViewPort2d( QWidget* parent, GLViewer_ViewFrame* theViewFrame ) :
48 GLViewer_ViewPort( parent ),
49 myMargin( MARGIN ), myWidth( WIDTH ), myHeight( HEIGHT ),
50 myXScale( 1.0 ), myYScale( 1.0 ), myXOldScale( 1.0 ), myYOldScale( 1.0 ),
51 myXPan( 0.0 ), myYPan( 0.0 ),
52 myIsMouseReleaseBlock( false )
54 if( theViewFrame == NULL )
55 myViewFrame = ( GLViewer_ViewFrame* )parent;
57 myViewFrame = theViewFrame;
61 myBorder = new GLViewer_Rect();
63 QBoxLayout* qbl = new QHBoxLayout( this );
64 myGLWidget = new GLViewer_Widget( this, 0 ) ;
65 qbl->addWidget( myGLWidget );
66 myGLWidget->setFocusProxy( this );
67 setMouseTracking( TRUE );
69 myIsDragProcess = noDrag;
70 //myCurDragMousePos = QPoint();
76 myViewPortId = aLastViewPostId;
82 myObjectTip = new QtxToolTip( myGLWidget );///GLViewer_ObjectTip( this );
83 myObjectTip->setShowDelayTime( 60000 );
84 connect( myObjectTip, SIGNAL( maybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ),
85 this, SLOT( onMaybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ) );
86 // myGLWidget->installEventFilter( myObjectTip );
89 GLViewer_ViewPort2d::~GLViewer_ViewPort2d()
101 void GLViewer_ViewPort2d::onStartDragObject( )
103 if( myIsDragProcess == noDrag )
105 myIsDragProcess = initDrag;
106 QCursor::setPos( (int)(*myCurDragPosX), (int)(*myCurDragPosY) );
107 //myCurDragMousePos = QPoint( 0, 0 );
108 delete myCurDragPosX;
109 delete myCurDragPosY;
110 myCurDragPosX = NULL;
111 myCurDragPosY = NULL;
116 void GLViewer_ViewPort2d::onCutObject()
118 /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
121 GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
122 aMimeSource->setObject( aMovingObject );
124 QClipboard *aClipboard = QApplication::clipboard();
126 aClipboard->setData( aMimeSource );
128 ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->deleteObject( aMovingObject );
130 GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
131 int aObjNum = aContext->NbSelected();
134 QValueList<GLViewer_Object*> aObjects;
135 GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
136 aContext->InitSelected();
137 for( ; aContext->MoreSelected(); aContext->NextSelected() )
138 aObjects.append( aContext->SelectedObject() );
140 //aMimeSource->setObjects( aObjects ); ouv 6.05.04
142 QClipboard *aClipboard = QApplication::clipboard();
144 aClipboard->setData( aMimeSource );
146 for( int i = 0; i < aObjNum; i++ )
147 aContext->deleteObject( aObjects[i] );
151 void GLViewer_ViewPort2d::onCopyObject()
153 /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
156 GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
157 aMimeSource->setObject( aMovingObject );
159 QClipboard *aClipboard = QApplication::clipboard();
161 aClipboard->setData( aMimeSource );
164 GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
165 int aObjNum = aContext->NbSelected();
168 QValueList<GLViewer_Object*> aObjects;
169 GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
170 aContext->InitSelected();
171 for( ; aContext->MoreSelected(); aContext->NextSelected() )
172 aObjects.append( aContext->SelectedObject() );
174 //aMimeSource->setObjects( aObjects ); ouv 6.05.04
176 QClipboard *aClipboard = QApplication::clipboard();
178 aClipboard->setData( aMimeSource );
182 void GLViewer_ViewPort2d::onPasteObject()
184 /*QClipboard *aClipboard = QApplication::clipboard();
185 QMimeSource* aMimeSource = aClipboard->data();
186 if( aMimeSource->provides( "GLViewer_Object" ) )
193 aType = aMimeSource->format( i );
194 anArray = aMimeSource->encodedData( aType );
195 if( anArray.size() != 0 )
200 if( anArray.size() == 0 )
203 GLViewer_Object* aObject = GLViewer_MimeSource::getObject( anArray, aType );
207 ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->insertObject( aObject, true );
211 QClipboard *aClipboard = QApplication::clipboard();
213 QMimeSource* aMimeSource = aClipboard->data();
214 if( aMimeSource->provides( "GLViewer_Objects" ) )
216 QByteArray anArray = aMimeSource->encodedData( "GLViewer_Objects" );
217 QValueList<GLViewer_Object*> aObjects = GLViewer_MimeSource::getObjects( anArray, "GLViewer_Objects" );
218 if( aObjects.empty() )
220 GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
221 for( int i = 0; i < aObjects.count(); i++ )
222 aContext->insertObject( aObjects[i], true );
227 void GLViewer_ViewPort2d::onDragObject( QMouseEvent* e )
229 //cout << "---GLViewer_ViewPort2d::onDragObject()---" << endl;
230 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
231 GLViewer_Context* aContext = aViewer->getGLContext();
232 GLViewer_Object* anObject = aContext->getCurrentObject();
237 float aX = e->pos().x();
238 float anY = e->pos().y();
239 aViewer->transPoint( aX, anY );
241 if( myCurDragPosX == NULL && myCurDragPosY == NULL )
243 myCurDragPosX = new float(aX);
244 myCurDragPosY = new float(anY);
248 //QPoint aNewPos = e->pos();
249 //GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
251 if( anObject && (e->state() & LeftButton ) )
253 if( aContext->isSelected( anObject ) )
255 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
257 GLViewer_Object* aMovingObject = aContext->SelectedObject();
259 aMovingObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
263 anObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
265 else if( aContext->NbSelected() && (e->state() & MidButton ) )
266 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
267 (aContext->SelectedObject())->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
269 delete myCurDragPosX;
270 delete myCurDragPosY;
271 myCurDragPosX = new float(aX);
272 myCurDragPosY = new float(anY);
274 myGLWidget->updateGL();
278 Emits 'mouseEvent' signal. [ virtual protected ]
280 void GLViewer_ViewPort2d::mousePressEvent( QMouseEvent* e )
282 emit vpMouseEvent( e );
284 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
285 GLViewer_Context* aContext = aViewer->getGLContext();
287 GLViewer_Object* anObject = NULL;
289 anObject = aContext->getCurrentObject();
291 bool accel = e->state() & GLViewer_ViewTransformer::accelKey();
292 if( ( anObject && !( accel || e->button() == Qt::RightButton ) ) ||
293 ( aContext->NbSelected() && !accel && e->button() == Qt::MidButton ) )
295 myIsDragProcess = inDrag;
300 Emits 'mouseEvent' signal. [ virtual protected ]
302 void GLViewer_ViewPort2d::mouseMoveEvent( QMouseEvent* e )
304 emit vpMouseEvent( e );
306 if( myIsDragProcess == inDrag )
309 /*GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
310 GLViewer_Context* aContext = aViewer->getGLContext();
312 GLViewer_Object* anObj = aContext->getCurrentObject();
313 if( anObj && aContext->currentObjectIsChanged() )
315 //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::add}" << endl;
316 //QToolTip::remove( myGLWidget );
317 QRect* aRect = (aViewer->getWinObjectRect(anObj));
318 //QToolTip::add( myGLWidget, *aRect, anObj->getToolTipText() );
319 myGLWidget->addToolTip( anObj->getToolTipText(), *aRect );
323 //cout << "GLViewer_ViewPort2d::mouseMoveEvent{QToolTip::remove}" << endl;
324 //QRect* aRect = (aViewer->getWinObjectRect(anObj));
325 //QToolTip::remove( myGLWidget, *aRect );
326 myGLWidget->removeToolTip();
331 Emits 'mouseEvent' signal. [ virtual protected ]
333 void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent* e )
335 if ( myIsMouseReleaseBlock )
337 // skip mouse release after double click
338 myIsMouseReleaseBlock = false;
342 /* show popup menu */
343 if ( e->button() == Qt::RightButton )
345 //QPopupMenu* popup = createPopup();
346 //if ( popup && popup->count() )
347 // popup->exec( QCursor::pos() );
348 //destroyPopup( /*popup*/ );
350 emit vpMouseEvent( e );
352 if( myIsDragProcess == inDrag )
354 bool isAnyMoved = false;
355 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
356 GLViewer_Context* aContext = aViewer->getGLContext();
357 GLViewer_Object* aMovingObject;
358 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
360 aMovingObject = aContext->SelectedObject();
362 isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
365 aMovingObject = aContext->getCurrentObject();
367 isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
369 myIsDragProcess = noDrag;
370 //myCurDragMousePos.setX( 0 );
371 //myCurDragMousePos.setY( 0 );
372 delete myCurDragPosX;
373 delete myCurDragPosY;
374 myCurDragPosX = NULL;
375 myCurDragPosY = NULL;
380 aViewer->updateBorders();
385 void GLViewer_ViewPort2d::mouseDoubleClickEvent( QMouseEvent * e )
387 //redefined to block mouse release after mouse double click
388 myIsMouseReleaseBlock = true;
389 // invoke base implementation
390 GLViewer_ViewPort::mouseDoubleClickEvent( e );
393 void GLViewer_ViewPort2d::turnCompass( GLboolean on )
396 myCompass = new GLViewer_Compass( Qt::green, 30, GLViewer_Compass::TopRight, 10, 5, 12, 3 );
401 void GLViewer_ViewPort2d::turnGrid( GLboolean on )
405 myGrid = new GLViewer_Grid( 2*WIDTH, 2*HEIGHT,
407 GRID_XSIZE, GRID_YSIZE,
409 myXScale, myYScale );
415 void GLViewer_ViewPort2d::setGridColor( const QColor gridColor, const QColor axisColor )
419 myGrid->setGridColor( ( GLfloat )gridColor.red() / 255,
420 ( GLfloat )gridColor.green() / 255,
421 ( GLfloat )gridColor.blue() / 255 );
422 myGrid->setAxisColor( ( GLfloat )axisColor.red() / 255,
423 ( GLfloat )axisColor.green() / 255,
424 ( GLfloat )axisColor.blue() / 255 );
428 void GLViewer_ViewPort2d::setBackgroundColor( const QColor& color )
430 GLViewer_ViewPort::setBackgroundColor( color );
431 myGLWidget->makeCurrent();
432 glClearColor( ( GLfloat )color.red() / 255,
433 ( GLfloat )color.green() / 255,
434 ( GLfloat )color.blue() / 255, 1.0 );
435 myGLWidget->repaint();
438 QColor GLViewer_ViewPort2d::backgroundColor() const
440 return GLViewer_ViewPort::backgroundColor();
443 void GLViewer_ViewPort2d::initResize( int x, int y )
445 float xa, xb, ya, yb;
446 xa = myBorder->left() - myMargin;
447 xb = myBorder->right() + myMargin;
448 ya = myBorder->top() - myMargin;
449 yb = myBorder->bottom() + myMargin;
451 GLfloat zoom, xzoom, yzoom;
456 xzoom = (GLfloat)x / myWidth;
457 yzoom = (GLfloat)y / myHeight;
459 if ( ( xzoom < yzoom ) && ( xzoom < 1 ) )
461 else if ( ( yzoom < xzoom ) && ( yzoom < 1 ) )
466 zoom = xzoom > yzoom ? xzoom : yzoom;
469 if ( !max && ( ! ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
470 ( ( myXPan - w/2 ) > xa * myXScale * zoom ) ||
471 ( ( myYPan + h/2 ) < yb * myYScale * zoom ) ||
472 ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) )
475 if ( max && ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
476 ( ( myXPan - w/2 ) > xa * myXScale * zoom ) ||
477 ( ( myYPan + h/2 ) < yb * myYScale * zoom ) ||
478 ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) )
488 myGrid->setResize( 2*x, 2*y, zoom );
490 myGLWidget->setScale( myXScale, myYScale, 1.0 );
493 void GLViewer_ViewPort2d::paintEvent( QPaintEvent* e )
495 //cout << "GLViewer_ViewPort2d::paintEvent" << endl;
496 myGLWidget->updateGL();
497 GLViewer_ViewPort::paintEvent( e );
500 void GLViewer_ViewPort2d::resizeEvent( QResizeEvent* e )
502 //cout << "GLViewer_ViewPort2d::resizeEvent" << endl;
503 GLViewer_ViewPort::resizeEvent( e );
506 void GLViewer_ViewPort2d::reset()
508 //cout << "GLViewer_ViewPort2d::reset" << endl;
511 GLint vpWidth, vpHeight;
513 myGLWidget->makeCurrent();
514 glGetIntegerv( GL_VIEWPORT, val );
518 GLint w = myGLWidget->getWidth();
519 GLint h = myGLWidget->getHeight();
520 GLfloat zoom = vpWidth / ( GLfloat )w < vpHeight / ( GLfloat )h ?
521 vpWidth / ( GLfloat )w : vpHeight / ( GLfloat )h;
525 myGrid->setPan( 0.0, 0.0 );
526 myGrid->setZoom( zoom / myXScale );
534 myGLWidget->setPan( myXPan, myYPan, 0.0 );
535 myGLWidget->setScale( myXScale, myYScale, 1.0 );
536 myGLWidget->setRotationAngle( 0.0 );
537 myGLWidget->setRotation( 0.0, 0.0, 0.0, 1.0 );
538 myGLWidget->updateGL();
541 void GLViewer_ViewPort2d::pan( int dx, int dy )
543 //cout << "GLViewer_ViewPort2d::pan " << dx << " " << dy << endl;
545 /*myXPan += dx / myXScale;
546 myYPan += dy / myYScale;
548 float ra, rx, ry, rz;
549 myGLWidget->getRotation( ra, rx, ry, rz );
550 GLfloat angle = ra * PI / 180.;
553 myGrid->setPan( myXPan*cos(angle) + myYPan*sin(angle),
554 -myXPan*sin(angle) + myYPan*cos(angle) );
557 float ra, rx, ry, rz;
558 myGLWidget->getRotation( ra, rx, ry, rz );
559 GLfloat angle = ra * PI / 180.;
561 myXPan += (dx*cos(angle) + dy*sin(angle)) / myXScale;
562 myYPan += (-dx*sin(angle) + dy*cos(angle)) / myXScale;
565 myGrid->setPan( myXPan, myYPan );
567 myGLWidget->setPan( myXPan, myYPan, 0.0 );
568 myGLWidget->setScale( myXScale, myYScale, 1.0 );
569 myGLWidget->updateGL();
572 void GLViewer_ViewPort2d::setCenter( int x, int y )
574 //cout << "GLViewer_ViewPort2d::setCenter" << endl;
577 GLint vpWidth, vpHeight;
579 myGLWidget->makeCurrent();
580 glGetIntegerv( GL_VIEWPORT, val );
584 myXPan -= ( x - vpWidth/2 ) / myXScale;
585 myYPan += ( y - vpHeight/2 ) / myYScale;
589 myGrid->setPan( myXPan, myYPan );
590 myGrid->setZoom( myXOldScale / myXScale );
593 myXScale = myXOldScale;
594 myYScale = myYOldScale;
596 myGLWidget->setPan( myXPan, myYPan, 0.0 );
597 myGLWidget->setScale( myXScale, myYScale, 1.0 );
598 myGLWidget->updateGL();
601 void GLViewer_ViewPort2d::zoom( int x0, int y0, int x, int y )
603 //cout << "GLViewer_ViewPort2d::zoom" << endl;
609 if ( dx == 0. && dy == 0. )
612 zm = sqrt(dx * dx + dy * dy) / 100. + 1;
613 zm = (dx > 0.) ? zm : 1. / zm;
623 if( myGrid->setZoom( zm ) )
625 myGLWidget->setPan( myXPan, myYPan, 0.0 );
626 myGLWidget->setScale( myXScale, myYScale, 1.0 );
627 myGLWidget->updateGL();
637 myGLWidget->setPan( myXPan, myYPan, 0.0 );
638 myGLWidget->setScale( myXScale, myYScale, 1.0 );
639 myGLWidget->updateGL();
643 void GLViewer_ViewPort2d::fitRect( const QRect& rect )
645 float x0, x1, y0, y1;
646 float dx, dy, zm, centerX, centerY;
649 GLint vpWidth, vpHeight;
651 myGLWidget->makeCurrent();
652 glGetIntegerv( GL_VIEWPORT, val );
661 dx = fabs( x1 - x0 );
662 dy = fabs( y1 - y0 );
663 centerX = ( x0 + x1 ) / 2.;
664 centerY = ( y0 + y1 ) / 2.;
666 if ( dx == 0. || dy == 0. )
669 zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy;
671 float aDX = ( vpWidth / 2. - centerX ) / myXScale;
672 float aDY = ( vpHeight / 2. - centerY ) / myYScale;
674 float ra, rx, ry, rz;
675 myGLWidget->getRotation( ra, rx, ry, rz );
676 GLfloat angle = ra * PI / 180.;
678 myXPan += (aDX*cos(angle) - aDY*sin(angle));
679 myYPan -= (aDX*sin(angle) + aDY*cos(angle));
682 myGrid->setPan( myXPan, myYPan );
688 myGrid->setZoom( zm );
690 myGLWidget->setPan( myXPan, myYPan, 0.0 );
691 myGLWidget->setScale( myXScale, myYScale, 1.0 );
692 myGLWidget->updateGL();
695 void GLViewer_ViewPort2d::fitSelect()
697 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
698 GLViewer_Context* aContext = aViewer->getGLContext();
703 for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
704 aSelRect |= *(aViewer->getWinObjectRect( aContext->SelectedObject() ));
706 if( aSelRect.isValid() )
708 aSelRect.setTop( aSelRect.top() - SELECTION_RECT_GAP );
709 aSelRect.setBottom( aSelRect.bottom() + SELECTION_RECT_GAP );
710 aSelRect.setLeft( aSelRect.left() - SELECTION_RECT_GAP );
711 aSelRect.setRight( aSelRect.right() + SELECTION_RECT_GAP );
716 void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
718 //cout << "GLViewer_ViewPort2d::fitAll" << endl;
720 float xa, xb, ya, yb;
722 float xScale, yScale;
724 myMargin = QMAX( myBorder->width(), myBorder->height() ) / 5;
726 xa = myBorder->left() - myMargin;
727 xb = myBorder->right() + myMargin;
728 ya = myBorder->bottom() - myMargin;
729 yb = myBorder->top() + myMargin;
731 float aPoints[8] = { xa, ya, xb, ya, xa, yb, xb, yb };
733 float ra, rx, ry, rz;
734 myGLWidget->getRotation( ra, rx, ry, rz );
735 float angle = ra * PI / 180.;
738 for( i = 0; i < 7; i = i + 2 )
739 rotate_point( aPoints[i], aPoints[i+1], angle );
741 float aBorders[4] = { aPoints[0], aPoints[0], aPoints[1], aPoints[1] };
743 for( i = 2; i < 7; i = i + 2 )
745 if( aBorders[0] < aPoints[i] )
746 aBorders[0] = aPoints[i];
747 if( aBorders[1] > aPoints[i] )
748 aBorders[1] = aPoints[i];
750 if( aBorders[2] < aPoints[i+1] )
751 aBorders[2] = aPoints[i+1];
752 if( aBorders[3] > aPoints[i+1] )
753 aBorders[3] = aPoints[i+1];
757 GLint vpWidth, vpHeight;
759 myGLWidget->makeCurrent();
760 glGetIntegerv( GL_VIEWPORT, val );
764 dx = fabs( aBorders[1] - aBorders[0] );
765 dy = fabs( aBorders[3] - aBorders[2] );
767 myXPan = -( aBorders[0] + aBorders[1] ) / 2;
768 myYPan = -( aBorders[2] + aBorders[3] ) / 2;
773 myXOldScale = myXScale;
774 myYOldScale = myYScale;
780 zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy;
789 myGrid->setPan( myXPan, myYPan );
791 myGrid->setZoom( zm / xScale );
793 myGrid->setZoom( zm / yScale );
796 myGLWidget->setPan( myXPan, myYPan, 0.0 );
797 myGLWidget->setScale( myXScale, myYScale, 1.0 );
798 myGLWidget->updateGL();
801 emit vpUpdateValues();
804 void GLViewer_ViewPort2d::startRotation( int x, int y )
806 myGLWidget->setRotationStart( x, y, 1.0 );
809 void GLViewer_ViewPort2d::rotate( int intX, int intY )
812 GLint vpWidth, vpHeight;
814 myGLWidget->makeCurrent();
815 glGetIntegerv( GL_VIEWPORT, val );
819 float x = intX, y = intY;
820 float x0 = vpWidth/2;
821 float y0 = vpHeight/2;
823 float xs, ys, zs, dx, dy;
824 myGLWidget->getRotationStart( xs, ys, zs );
833 float l1 = pow( double( xs*xs + ys*ys ), 0.5 );
834 float l2 = pow( double( x*x + y*y ), 0.5 );
835 float l = pow( double( dx*dx + dy*dy ), 0.5 );
837 double mult = xs * y - x * ys;
839 if( mult > 0 ) sign = 1;
840 else if( mult < 0 ) sign = -1;
843 float anglePrev = myGLWidget->getRotationAngle();
844 float angleNew = sign * acos( ( l1*l1 + l2*l2 - l*l ) / ( 2 * l1 * l2 )) * 180. / PI;
845 float angle = anglePrev + angleNew;
847 // GLfloat anAngle = angle * PI / 180.; unused
849 float ra, rx, ry, rz;
850 myGLWidget->getRotation( ra, rx, ry, rz );
851 myGLWidget->setRotation( angle, rx, ry, rz );
852 myGLWidget->updateGL();
855 void GLViewer_ViewPort2d::endRotation()
857 float ra, rx, ry, rz;
858 myGLWidget->getRotation( ra, rx, ry, rz );
859 myGLWidget->setRotationAngle( ra );
862 void GLViewer_ViewPort2d::drawCompass()
864 if( !myCompass->getVisible() )
867 GLfloat xScale, yScale, xPan, yPan;
869 int xPos = getWidth();
870 int yPos = getHeight();
872 int cPos = myCompass->getPos();
873 int cSize = myCompass->getSize();
874 QColor cCol = myCompass->getColor();
875 int cWidthTop = myCompass->getArrowWidthTop();
876 int cWidthBot = myCompass->getArrowWidthBottom();
877 int cHeightTop = myCompass->getArrowHeightTop();
878 int cHeightBot = myCompass->getArrowHeightBottom();
880 GLfloat colorR = (cCol.red())/255;
881 GLfloat colorG = (cCol.green())/255;
882 GLfloat colorB = (cCol.blue())/255;
884 float delX = cSize * 0.5;
885 float delY = cSize * 0.5;
887 getScale( xScale, yScale );
890 float centerX = (xPos/2 - delX - cSize)/xScale;
891 float centerY = (yPos/2 - delY - cSize)/yScale;
895 case GLViewer_Compass::TopLeft:
898 case GLViewer_Compass::BottomLeft:
902 case GLViewer_Compass::BottomRight:
908 float ra, rx, ry, rz;
909 myGLWidget->getRotation( ra, rx, ry, rz );
910 GLfloat angle = ra * PI / 180.;
911 GLfloat /*r = 0.0,*/ x = 0.0 , y = 0.0;
913 rotate_point( centerX, centerY, -angle );
918 glColor3f( colorR, colorG, colorB );
919 glBegin( GL_POLYGON );
921 x = centerX; y = centerY + cSize / yScale;
924 x = centerX + cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
927 x = centerX + cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
930 x = centerX + cWidthBot / xScale; y = centerY - cSize/yScale;
933 x = centerX; y = centerY - (cSize - cHeightBot) / yScale ;
936 x = centerX - cWidthBot / xScale; y = centerY - cSize/yScale;
939 x = centerX - cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
942 x = centerX - cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
946 glEnable( GL_LINE_SMOOTH );
947 glBegin(GL_LINE_LOOP);
949 float aCircAngle = 0;
950 for ( int i = 0; i < 20 * SEGMENTS + 1; i++ )
952 x = centerX + cos(aCircAngle) * cSize / xScale;
953 y = centerY + sin(aCircAngle) * cSize / yScale;
955 aCircAngle += float( STEP ) / 2;
959 GLdouble modelMatrix[16], projMatrix[16];
961 GLdouble winxN, winyN, winz;
962 GLdouble winxE, winyE;
963 GLdouble winxS, winyS;
964 GLdouble winxW, winyW;
967 GLViewer_TexFont* aFont = myCompass->getFont();
968 float widN = (float)aFont->getStringWidth( "N" );
969 float widW = (float)aFont->getStringWidth( "W" );
970 float widS = (float)aFont->getStringWidth( "S" );
971 float widE = (float)aFont->getStringWidth( "E" );
972 float heightL = (float)aFont->getStringHeight();
974 float xGapN = - widN/2 *( 1.0 + sin(angle) );
975 float xGapS = - widS/2 *( 1.0 - sin(angle) );
976 float xGapW = - widW/2 *( 1.0 + cos(angle) );
977 float xGapE = - widE/2 *( 1.0 - cos(angle) );
979 float yGapN = - heightL/2 *( 1.0 - cos(angle) ) * 0.75;
980 float yGapS = - heightL/2 *( 1.0 + cos(angle) ) * 0.75;
981 float yGapW = - heightL/2 *( 1.0 + sin(angle) ) * 0.75;
982 float yGapE = - heightL/2 *( 1.0 - sin(angle) ) * 0.75;
984 glGetIntegerv (GL_VIEWPORT, viewport);
985 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
986 glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
988 gluProject (centerX, centerY + cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxN, &winyN, &winz);
989 gluProject (centerX + cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxE, &winyE, &winz);
990 gluProject (centerX, centerY - cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxS, &winyS, &winz);
991 gluProject (centerX - cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxW, &winyW, &winz);
993 glColor3f( 1.0, 1.0, 1.0 );
995 aTextList = glGenLists( 1 );
996 glNewList( aTextList, GL_COMPILE );
998 glMatrixMode(GL_PROJECTION);
1001 glOrtho(0,viewport[2],0,viewport[3],-100,100);
1002 glMatrixMode(GL_MODELVIEW);
1006 aFont->drawString( "N", winxN + xGapN, winyN + yGapN );
1007 aFont->drawString( "E", winxE + xGapE, winyE + yGapE );
1008 aFont->drawString( "S", winxS + xGapS, winyS + yGapS );
1009 aFont->drawString( "W", winxW + xGapW, winyW + yGapW );
1011 glMatrixMode(GL_PROJECTION);
1013 glMatrixMode(GL_MODELVIEW);
1018 if ( aTextList != -1 )
1019 glCallList( aTextList );
1022 BlockStatus GLViewer_ViewPort2d::currentBlock()
1024 if( myIsDragProcess == inDrag && myCurDragPosX != NULL && myCurDragPosY != NULL)
1025 return BlockStatus(BS_Highlighting | BS_Selection);
1027 if( mypFirstPoint && mypLastPoint )
1028 return BlockStatus(BS_Highlighting | BS_Selection);
1033 void GLViewer_ViewPort2d::startSelectByRect( int x, int y )
1035 if( !mypFirstPoint && !mypLastPoint )
1037 mypFirstPoint = new QPoint( x, y );
1038 mypLastPoint = new QPoint( x, y );
1041 void GLViewer_ViewPort2d::drawSelectByRect( int x, int y )
1043 if( mypFirstPoint && mypLastPoint )
1046 QPainter p( getPaintDevice() );
1047 p.setPen( Qt::white );
1048 p.setRasterOp( Qt::XorROP );
1050 p.drawRect( selectionRect() ); /* erase */
1052 mypLastPoint->setX( x );
1053 mypLastPoint->setY( y );
1055 p.drawRect( selectionRect() ); /* draw */
1059 void GLViewer_ViewPort2d::finishSelectByRect()
1061 if( mypFirstPoint && mypLastPoint )
1064 QPainter p( getPaintDevice() );
1065 p.setPen( Qt::white );
1066 p.setRasterOp( Qt::XorROP );
1068 p.drawRect( selectionRect() ); /* erase */
1070 delete mypFirstPoint;
1071 delete mypLastPoint;
1073 mypFirstPoint = NULL;
1074 mypLastPoint = NULL;
1078 QRect GLViewer_ViewPort2d::selectionRect()
1081 if( mypFirstPoint && mypLastPoint )
1083 aRect.setLeft( QMIN( mypFirstPoint->x(), mypLastPoint->x() ) );
1084 aRect.setTop( QMIN( mypFirstPoint->y(), mypLastPoint->y() ) );
1085 aRect.setRight( QMAX( mypFirstPoint->x(), mypLastPoint->x() ) );
1086 aRect.setBottom( QMAX( mypFirstPoint->y(), mypLastPoint->y() ) );
1092 bool GLViewer_ViewPort2d::startPulling( GLViewer_Pnt point )
1094 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
1095 GLViewer_Context* aContext = aViewer->getGLContext();
1096 ObjList anObjects = aContext->getObjects();
1098 for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
1100 GLViewer_Object* anObject = *it;
1101 GLViewer_Rect aRect = anObject->getPullingRect();
1103 if( aRect.contains( point ) && anObject->startPulling( point ) )
1106 myPullingObject = anObject;
1107 setCursor( *getHandCursor() );
1115 void GLViewer_ViewPort2d::drawPulling( GLViewer_Pnt point )
1117 GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
1118 GLViewer_Context* aContext = aViewer->getGLContext();
1119 ObjList anObjects = aContext->getObjects();
1121 GLViewer_Object* aLockedObject = 0;
1122 for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
1124 GLViewer_Object* anObject = *it;
1125 if( !anObject->getVisible() )
1128 GLViewer_Rect aRect = anObject->getPullingRect();
1130 if( aRect.contains( point ) && anObject->portContains( point ) )
1132 aLockedObject = anObject;
1137 myPullingObject->pull( point, aLockedObject );
1140 void GLViewer_ViewPort2d::finishPulling()
1142 myIsPulling = false;
1143 myPullingObject->finishPulling();
1144 setCursor( *getDefaultCursor() );
1147 GLViewer_Rect GLViewer_ViewPort2d::win2GLV( const QRect& theRect ) const
1149 GLViewer_Rect aRect;
1151 GLdouble modelMatrix[16], projMatrix[16];
1154 GLdouble objx1, objy1;
1155 GLdouble objx2, objy2;
1158 glGetIntegerv (GL_VIEWPORT, viewport);
1159 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1160 glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1162 gluUnProject( theRect.left(), viewport[3] - theRect.top(), 0, modelMatrix, projMatrix, viewport, &objx1, &objy1, &objz );
1163 gluUnProject( theRect.right(), viewport[3] - theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &objx2, &objy2, &objz );
1165 aRect.setLeft( objx1 );
1166 aRect.setTop( objy1 );
1167 aRect.setRight( objx2 );
1168 aRect.setBottom( objy2 );
1173 QRect GLViewer_ViewPort2d::GLV2win( const GLViewer_Rect& theRect ) const
1177 GLdouble modelMatrix[16], projMatrix[16];
1180 GLdouble winx1, winy1;
1181 GLdouble winx2, winy2;
1184 glGetIntegerv (GL_VIEWPORT, viewport);
1185 glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1186 glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1188 gluProject( theRect.left(), theRect.top(), 0, modelMatrix, projMatrix, viewport, &winx1, &winy1, &winz );
1189 gluProject( theRect.right(), theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &winx2, &winy2, &winz );
1191 aRect.setLeft( (int)winx1 );
1192 aRect.setTop( viewport[3] - (int)winy1 );
1193 aRect.setRight( (int)winx2 );
1194 aRect.setBottom( viewport[3] - (int)winy2 );
1199 void GLViewer_ViewPort2d::onMaybeTip( QPoint thePoint, QString& theText, QFont& theFont, QRect& theTextReg, QRect& theRegion )
1201 GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
1203 GLViewer_Object* anObj = aContext->getCurrentObject();
1206 theText = anObj->getToolTipText();
1207 if( theText.isEmpty() )
1208 theText = anObj->getName();
1211 if( anObj->isTooTipHTML() )
1212 aList = QStringList::split( "<br>", theText );
1214 aList = QStringList::split( "\n", theText );
1216 if( !aList.isEmpty() )
1219 int str_size = aList.first().length();
1220 for( int i = 1, size = aList.count(); i < size; i++ )
1222 if( str_size < aList[i].length() )
1225 str_size = aList[i].length();
1229 int cur_height = 24;
1230 QCursor* aCursor = QApplication::overrideCursor();
1233 const QBitmap* aBitmap = aCursor->bitmap();
1235 cur_height = aBitmap->height();
1239 QSize aSize = QLabel( theText, 0 ).sizeHint();
1240 theTextReg = QRect( thePoint.x(), thePoint.y() + cur_height,
1241 aSize.width(), aSize.height() );
1242 theRegion = QRect( thePoint.x(), thePoint.y(), 1, 1 );