1 // Copyright (C) 2007-2023 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // Author : OPEN CASCADE
24 // File: GLViewer_Viewer2d.cxx
25 // Created: November, 2004
26 //#include <GLViewerAfx.h>
28 #include "GLViewer_Viewer2d.h"
29 #include "GLViewer_Object.h"
30 #include "GLViewer_ViewFrame.h"
31 #include "GLViewer_BaseObjects.h"
32 #include "GLViewer_CoordSystem.h"
33 #include "GLViewer_Context.h"
34 #include "GLViewer_Drawer.h"
35 #include "GLViewer_Selector2d.h"
36 #include "GLViewer_ViewPort2d.h"
38 #include "SUIT_Desktop.h"
39 #include "SUIT_ViewWindow.h"
40 #include "SUIT_ViewManager.h"
46 #include <QMouseEvent>
47 #include <QColorDialog>
51 \param title - viewer title
53 GLViewer_Viewer2d::GLViewer_Viewer2d( const QString& title) :
54 GLViewer_Viewer( title )
56 myGLContext = new GLViewer_Context( this );
60 mySelMode = GLViewer_Viewer::Multiple;
68 GLViewer_Viewer2d::~GLViewer_Viewer2d()
71 //delete myGLSketcher;
72 GLViewer_TexFont::clearTextBases();
75 /*!Create new instance of view window on desktop \a theDesktop.
76 *\retval SUIT_ViewWindow* - created view window pointer.
78 SUIT_ViewWindow* GLViewer_Viewer2d::createView( SUIT_Desktop* theDesktop )
80 return new GLViewer_ViewFrame( theDesktop, this );
84 Adds item for change background color
85 \param thePopup - menu
87 void GLViewer_Viewer2d::addPopupItems( QMenu* thePopup )
89 // CTH8434. "Change background color" menu item is available if there are no selected objects
90 if ( getSelector() == 0 || getSelector()->numSelected() == 0 )
92 if( thePopup->actions().count() > 0 )
93 thePopup->addSeparator();
94 thePopup->addAction( tr( "CHANGE_BGCOLOR" ), this, SLOT( onChangeBgColor() ) );
99 Changes background color
101 void GLViewer_Viewer2d::onChangeBgColor()
103 if( !getActiveView() )
105 GLViewer_ViewPort2d* vp = ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() );
107 QColor selColor = QColorDialog::getColor( vp->backgroundColor(), vp );
108 if ( selColor.isValid() ) {
109 vp->setBackgroundColor( selColor );
114 Updates colors for all drawers (does not work)
116 void GLViewer_Viewer2d::updateColors( QColor /*colorH*/, QColor /*colorS*/ )
118 activateAllDrawers( true );
122 Updates rect of global scene by adding new rectangle
123 \param theRect - rectangle
125 void GLViewer_Viewer2d::updateBorders( GLViewer_Rect* theRect )
127 QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
128 for ( int i = 0, n = views.count(); i < n; i++ )
130 GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
132 border->setLeft( qMin( border->left(), theRect->left() ) );
133 border->setRight( qMax( border->right(), theRect->right() ) );
134 border->setBottom( qMin( border->bottom(), theRect->bottom() ) );
135 border->setTop( qMax( border->top(), theRect->top() ) );
140 Recomputes global scene rect
142 void GLViewer_Viewer2d::updateBorders()
144 QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
146 ObjList anObjects = myGLContext->getObjects();
147 ObjList::Iterator beginIt = anObjects.begin();
148 ObjList::Iterator endIt = anObjects.end();
149 for ( int i = 0, n = views.count(); i < n; i++ )
151 GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
154 border->setIsEmpty( true );
155 // initialise border by default values to avoid old values
156 border->setCoords( 0, 0, 0, 0 );
157 for ( ObjList::Iterator it = beginIt; it != endIt; ++it )
159 GLViewer_Object* anObject = *it;
160 GLViewer_Rect* aRect = anObject->getRect();
161 if( !anObject->isSelectable() || !anObject->getVisible() )
164 if( border->isEmpty() )
166 border->setIsEmpty( false );
167 border->setCoords( aRect->left(), aRect->right(), aRect->bottom(), aRect->top() );
171 border->setLeft( qMin( border->left(), aRect->left() ) );
172 border->setRight( qMax( border->right(), aRect->right() ) );
173 border->setBottom( qMin( border->bottom(), aRect->bottom() ) );
174 border->setTop( qMax( border->top(), aRect->top() ) );
181 Redraws all active objects by updating all drawers in all views
183 void GLViewer_Viewer2d::updateAll()
185 if ( !getActiveView() )
188 QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
189 for ( int i = 0, n = views.count(); i < n; i++ )
190 ( ( GLViewer_ViewPort2d* )( ( GLViewer_ViewFrame* )views[i] )->getViewPort() )->getGLWidget()->updateGL();
194 \param onlyUpdate is passed to method activateAllDrawers drawers
196 void GLViewer_Viewer2d::updateDrawers( GLboolean update, GLfloat /*scX*/, GLfloat /*scY*/ )
198 activateAllDrawers( update );
202 Activates drawers for objects from list \param theObjects only
204 void GLViewer_Viewer2d::activateDrawers( QList<GLViewer_Object*>& theObjects, bool onlyUpdate, GLboolean swap )
206 //cout << "GLViewer_Viewer2d::activateDrawers " << (int)onlyUpdate << " " << (int)swap << endl;
207 QList<GLViewer_Drawer*>::Iterator anIt = myDrawers.begin();
208 QList<GLViewer_Drawer*>::Iterator endDIt = myDrawers.end();
209 for( ; anIt != endDIt; anIt++ )
212 QList<GLViewer_Drawer*> anActiveDrawers;
213 QList<GLViewer_Object*>::Iterator endOIt = theObjects.end();
215 for( QList<GLViewer_Object*>::Iterator oit = theObjects.begin(); oit != endOIt; ++oit )
217 GLViewer_Drawer* aDrawer = (*oit)->getDrawer();
220 anIt = myDrawers.begin();
221 endDIt = myDrawers.end();
223 for( ; anIt != endDIt; anIt++ )
224 if( (*anIt)->getObjectType() == (*oit)->getObjectType() )
226 (*oit)->setDrawer( *anIt );
233 myDrawers.append( (*oit)->createDrawer() );
234 aDrawer = (*oit)->getDrawer();
239 aDrawer->addObject( (*oit) );
241 int aPriority = aDrawer->getPriority();
243 if( anActiveDrawers.indexOf( aDrawer ) != -1 )
246 QList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
247 QList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
248 for( ; aDIt != aDEndIt; ++aDIt )
249 if( (*aDIt)->getPriority() > aPriority )
252 anActiveDrawers.insert( aDIt, aDrawer );
255 QList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
256 QList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
258 QVector<SUIT_ViewWindow*> views = getViewManager()->getViews();
259 for ( int i = 0, n = views.count(); i < n; i++ )
261 float xScale, yScale;
262 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort();
263 vp->getScale( xScale, yScale );
264 vp->getGLWidget()->makeCurrent();
266 for( ; aDIt != aDEndIt; aDIt++ )
268 GLViewer_Drawer* aDrawer = *aDIt;
270 aDrawer->create( xScale, yScale, onlyUpdate );
274 GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
275 (*aDIt)->drawRectangle( border, Qt::blue );
277 QString coords = QString::number( border->left() ) + " " + QString::number( border->right() ) + " " +
278 QString::number( border->bottom() ) + " " + QString::number( border->top() );
279 (*aDIt)->drawText( "Border : " + coords, border->left(), border->top() + 10 / yScale,
280 Qt::blue, &QFont( "Courier", 8, QFont::Normal ), 2 );
283 vp->getGLWidget()->swapBuffers();
286 ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() )->getGLWidget()->makeCurrent();
290 Activates drawer for \param theObject
292 void GLViewer_Viewer2d::activateDrawer( GLViewer_Object* theObject, bool onlyUpdate, GLboolean swap )
295 aList.append( theObject );
296 activateDrawers( aList, onlyUpdate, swap );
300 \param onlyUpdate is passed to drawers
302 void GLViewer_Viewer2d::activateAllDrawers( bool onlyUpdate, GLboolean swap )
304 if ( !getActiveView() )
307 ObjList anActiveObjs;
308 const ObjList& objs = myGLContext->getObjects();
309 for( ObjList::const_iterator it = objs.begin(); it != objs.end(); ++it )
311 GLViewer_Object* obj = (GLViewer_Object*)(*it);
312 if( obj->getVisible() )
313 anActiveObjs.append( obj );
316 activateDrawers( anActiveObjs, onlyUpdate, swap );
320 Creates set of marker
321 \param theMarkersNum - number of markers
322 \param theMarkersRad - radius of markers
324 void GLViewer_Viewer2d::onCreateGLMarkers( int theMarkersNum, int theMarkersRad )
326 if ( !getActiveView() )
329 GLViewer_MarkerSet* aMarkerSet = new GLViewer_MarkerSet( theMarkersNum, theMarkersRad );
330 getGLContext()->insertObject( aMarkerSet );
332 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
333 int vpWidth = vp->getWidth();
334 int vpHeight = vp->getHeight();
336 float* aXCoord = new float[ theMarkersNum ];
337 float* anYCoord = new float[ theMarkersNum ];
340 for ( long i = 0; i < theMarkersNum; i++ )
342 aXCoord[i] = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
343 anYCoord[i] = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
346 aMarkerSet->setXCoord( aXCoord, theMarkersNum );
347 aMarkerSet->setYCoord( anYCoord, theMarkersNum );
348 aMarkerSet->compute();
350 updateBorders( aMarkerSet->getRect() );
352 activateAllDrawers( false );
353 activateTransform( GLViewer_Viewer::FitAll );
361 \param theAnglesNum - number of angles
362 \param theRadius - radius
363 \param thePolylineNumber - number
365 void GLViewer_Viewer2d::onCreateGLPolyline( int theAnglesNum, int theRadius, int thePolylineNumber )
367 if ( !getActiveView() )
370 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
371 int vpWidth = vp->getWidth();
372 int vpHeight = vp->getHeight();
374 float* aXCoord = new float[ theAnglesNum ];
375 float* anYCoord = new float[ theAnglesNum ];
377 //srand( ( unsigned )time( NULL ) );
379 for( int j = 0; j < thePolylineNumber; j++)
381 GLViewer_Polyline* aPolyline = new GLViewer_Polyline( theAnglesNum, theRadius );
382 getGLContext()->insertObject( aPolyline );
384 float aXOffset = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
385 float anYOffset = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
386 for( int i = 0; i < theAnglesNum; i++ )
388 aXCoord[i] = cos( 2. * PI * i / theAnglesNum ) * theRadius + aXOffset;
389 anYCoord[i] = sin( 2. * PI * i / theAnglesNum ) * theRadius + anYOffset;
392 aPolyline->setHighSelAll( true );
393 aPolyline->setClosed( true );
394 aPolyline->setXCoord( aXCoord, theAnglesNum );
395 aPolyline->setYCoord( anYCoord, theAnglesNum );
396 aPolyline->compute();
398 updateBorders( aPolyline->getRect() );
401 activateAllDrawers( false );
402 activateTransform( GLViewer_Viewer::FitAll );
410 \param theStr - text string
411 \param theTextNumber - number
413 void GLViewer_Viewer2d::onCreateGLText( QString theStr, int theTextNumber )
415 if ( !getActiveView() )
418 if( theTextNumber <= 0 )
421 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
422 int vpWidth = vp->getWidth();
423 int vpHeight = vp->getHeight();
425 //srand( ( unsigned )time( NULL ) );
427 for( int j = 0; j < theTextNumber; j++)
429 float aXPos = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
430 float anYPos = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
431 QColor aColor( 255, 0, 255 );
433 GLViewer_TextObject* aText = new GLViewer_TextObject( theStr, aXPos, anYPos, aColor );
435 getGLContext()->insertObject( aText );
437 updateBorders( aText->getRect() );
440 activateAllDrawers( false );
444 Translates point from global CS to curreent viewer CS
445 \param x, y - co-ordinates to be translated
447 void GLViewer_Viewer2d::transPoint( GLfloat& x, GLfloat& y )
449 if ( !getActiveView() )
452 GLfloat xScale, yScale;
455 GLViewer_ViewPort2d* curvp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
457 curvp->getScale( xScale, yScale );
458 curvp->getPan( xPan, yPan );
460 GLfloat a = curvp->getGLWidget()->getRotationAngle() * PI / 180.;
462 x = ( x - ( GLfloat )curvp->getWidth() / 2 ) / xScale;
463 y = ( -y + ( GLfloat )curvp->getHeight() / 2 ) / yScale;
468 x = x1 * cos(a) + y1 * sin(a);
469 y = -x1 * sin(a) + y1 * cos(a);
476 \return object rect in window CS
477 \param theObject - object
479 QRect* GLViewer_Viewer2d::getWinObjectRect( GLViewer_Object* theObject )
481 if ( !getActiveView() )
484 GLfloat xScale, yScale;
487 GLViewer_ViewPort2d* curvp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
488 GLfloat aWidth = curvp->getWidth();
489 GLfloat aHeight = curvp->getHeight();
492 curvp->getScale( xScale, yScale );
493 curvp->getPan( xPan, yPan );
495 QRect aObjRect = theObject->getRect()->toQRect();
496 float aLeft = aObjRect.left() + xPan, aRight = aObjRect.right() + xPan;
497 float aTop = aObjRect.top() + yPan, aBot = aObjRect.bottom() + yPan;
499 GLfloat anAngle = curvp->getGLWidget()->getRotationAngle() * PI / 180.;
501 QPolygon aPointArray(4);
502 aPointArray[0] = QPoint( (int)(aLeft*cos(anAngle) - aTop*sin(anAngle)),
503 (int)(aLeft*sin(anAngle) + aTop*cos(anAngle)) );
504 aPointArray[1] = QPoint( (int)(aRight*cos(anAngle) - aTop*sin(anAngle)),
505 (int)(aRight*sin(anAngle) + aTop*cos(anAngle)) );
506 aPointArray[2] = QPoint( (int)(aRight*cos(anAngle) - aBot*sin(anAngle)),
507 (int)(aRight*sin(anAngle) + aBot*cos(anAngle)) );
508 aPointArray[3] = QPoint( (int)(aLeft*cos(anAngle) - aBot*sin(anAngle)),
509 (int)(aLeft*sin(anAngle) + aBot*cos(anAngle)) );
511 int aMinLeft = aPointArray[0].x(), aMaxRight = aPointArray[0].x(),
512 aMinTop = aPointArray[0].y(), aMaxBottom = aPointArray[0].y();
513 for( int i = 1; i < 4; i++ )
515 int x = aPointArray[i].x();
516 int y = aPointArray[i].y();
517 aMinLeft = qMin( aMinLeft,x );
518 aMaxRight = qMax( aMaxRight, x );
519 aMinTop = qMin( aMinTop, y );
520 aMaxBottom = qMax( aMaxBottom, y );
523 aLeft = (aMinLeft/* + xPan*/)*xScale + aWidth / 2;
524 aRight = (aMaxRight/* + xPan*/)*xScale + aWidth / 2;
526 aTop = -( (aMaxBottom/* + yPan*/)*yScale - aHeight / 2 );
527 aBot = -( (aMinTop/* + yPan*/)*yScale - aHeight / 2 );
529 QRect* newRect = new QRect( (int)aLeft, (int)aTop, (int)(aRight-aLeft), (int)(aBot-aTop) );
535 Translates rect in window CS to rect in global CS
536 \param theRect - rectangle to be translated
537 \return transformed rect
539 GLViewer_Rect GLViewer_Viewer2d::getGLVRect( const QRect& theRect ) const
541 if ( !getActiveView() )
542 return GLViewer_Rect();
544 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
547 return GLViewer_Rect();
549 return vp->win2GLV( theRect );
553 Translates rect in global CS to rect in window CS
554 \param theRect - rectangle to be translated
555 \return transformed rect
557 QRect GLViewer_Viewer2d::getQRect( const GLViewer_Rect& theRect ) const
559 if ( !getActiveView() )
562 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
567 return vp->GLV2win( theRect );
573 GLViewer_Selector* GLViewer_Viewer2d::createSelector()
575 return new GLViewer_Selector2d( this, getGLContext() );
579 \return new Transformer
580 \param type - type of new transformer
582 GLViewer_ViewTransformer* GLViewer_Viewer2d::createTransformer( int type )
584 return new GLViewer_View2dTransformer( this, type );
588 Custom mouse event handler
590 void GLViewer_Viewer2d::onMouseEvent( SUIT_ViewWindow*, QMouseEvent* e )
592 if ( !getActiveView() )
595 //if ( testRotation( e ) )
600 case QEvent::MouseButtonPress :
601 case QEvent::MouseMove :
602 case QEvent::MouseButtonRelease :
603 //if( myGLSketcher->getType() != None )
604 // myGLSketcher->sketch( e );
608 GLViewer_Viewer::onMouseEvent( 0, e );
612 Rotation transformation
614 bool GLViewer_Viewer2d::testRotation( QMouseEvent* e )
616 if ( ( (int)e->button() == GLViewer_View2dTransformer::rotateButton() ) && // todo Qt::MouseButton is unsigned int: comparison of int with uint
617 ( e->type() == QEvent::MouseButtonPress ) &&
618 ( e->modifiers() & GLViewer_ViewTransformer::accelKey() ) )
620 activateTransform( GLViewer_Viewer::Rotate );
627 Inserts text lines as header for file
628 \param aType - file type
629 \param hFile - file instance
631 void GLViewer_Viewer2d::insertHeader( VectorFileType aType, QFile& hFile )
633 if( aType == POST_SCRIPT )
635 QString header = "%!PS-Adobe-3.0\n";
636 header += "%%Creator: OpenCascade 2004\n";
637 header += "%%Title: Our document\n";
638 header += "%%PageOrder: Ascend\n";
639 header += "%%Orientation: Portrait\n";
640 header += "%%LanguageLevel: 2\n";
642 header += "%%Pages: 1\n";
643 header += "%%Page: 1\n\n";
645 hFile.write( header.toLatin1() );
647 else if( aType == HPGL )
649 QString header = "[Esc].(;\n";
650 header += "[Esc].I81;;17:\n";
651 header += "[Esc].N;19:\n";
659 hFile.write( header.toLatin1() );
664 Inserts text lines as ending for file
665 \param aType - file type
666 \param hFile - file instance
668 void GLViewer_Viewer2d::insertEnding( VectorFileType aType, QFile& hFile )
670 if( aType == POST_SCRIPT )
672 QString ending = "showpage\n\n%%EOF";
673 hFile.write( ending.toLatin1() );
675 else if( aType == HPGL )
677 QString ending = "PU;PA0,0;SP;EC;PG1;EC1;OE\n";
678 hFile.write( ending.toLatin1() );
682 inline void mm2custom( GLViewer_Viewer2d::VectorFileType aType, double& value )
684 if( aType==GLViewer_Viewer2d::POST_SCRIPT )
685 value*=2.8346; //mm to pt
687 else if( aType==GLViewer_Viewer2d::HPGL )
688 value*=40; //mm to plu (there are 40 plues in mm)
690 else if( aType==GLViewer_Viewer2d::ENH_METAFILE )
691 value*=100; //this unit is 1/100 mm
696 Translates current view content to vector file
697 \param aType - type of file
698 \param FileName - name of file,
699 \param aPType - paper size type
700 \param mmLeft, mmRight, mmTop, mmBottom - margins
702 bool GLViewer_Viewer2d::translateTo( VectorFileType aType, QString FileName, PaperType aPType,
703 double mmLeft, double mmRight, double mmTop, double mmBottom )
705 if ( !getActiveView() )
708 QFile hFile( FileName.toUtf8() );
714 GLViewer_ViewPort2d* aCurVP = (GLViewer_ViewPort2d*) getActiveView()->getViewPort();
717 aCurVP->getPan( xPan, yPan );
718 GLfloat aRotation = aCurVP->getGLWidget()->getRotationAngle() * 3.14159265 / 180.0;
720 GLViewer_CoordSystem aViewerCS( GLViewer_CoordSystem::Cartesian, xPan, yPan, 1.0, 1.0, aRotation );
722 double AW = Sizes[2*int(aPType)],
723 AH = Sizes[2*int(aPType)+1]; //size of Axx paper in mm
725 mm2custom( aType, mmLeft ); //we translate mm to custom units
726 mm2custom( aType, mmRight );
727 mm2custom( aType, mmTop );
728 mm2custom( aType, mmBottom );
729 mm2custom( aType, AW );
730 mm2custom( aType, AH );
732 float xScale, yScale;
733 aCurVP->getScale( xScale, yScale );
735 double VPWidth = aCurVP->getWidth()/xScale, //the width in reference units
736 VPHeight = aCurVP->getHeight()/yScale;
738 double k1 = ( AW-mmLeft-mmRight ) / VPWidth,
739 k2 = ( AH-mmTop-mmBottom ) / VPHeight;
742 k1 = k2; //We select the minimum
744 double hdelta = ( AW-mmLeft-mmRight - VPWidth * k1 )/2.0, //addition in horizontal
745 vdelta = ( AH-mmTop-mmBottom - VPHeight * k1 )/2.0; //addition in vertical
747 mmLeft += hdelta; //The real free space on the left and right borders
752 GLViewer_CoordSystem aPaperCS( GLViewer_CoordSystem::Cartesian,
753 -(mmLeft/k1+VPWidth/2.0), -(mmBottom/k1+VPHeight/2.0), 1/k1, 1/k1 );
755 if( aType==POST_SCRIPT || aType==HPGL )
757 hFile.open( QIODevice::ReadWrite | QIODevice::Truncate );
759 insertHeader( aType, hFile );
762 else if( aType==ENH_METAFILE )
765 r.left = 0; r.right = AW;
766 r.top = 0; r.bottom = AH;
767 HDC screen_dc = GetDC( 0 ); //The screen device context
768 HDC bitDC = CreateCompatibleDC ( screen_dc ); //The context compatible with screen
771 LPTSTR str = new TCHAR[FileName.length() + 1];
772 str[FileName.toWCharArray(str)] = '\0';
775 QByteArray arr = FileName.toLatin1();
776 LPTSTR str = arr.constData();
780 hMetaFileDC = CreateEnhMetaFile( bitDC, str, &r, empty );
784 SetMapMode( hMetaFileDC, MM_HIMETRIC );
785 SetWindowOrgEx( hMetaFileDC, 0, r.bottom, NULL );
786 HRGN ClipRgn = CreateRectRgn( 0, 0, AW, AH );
787 SelectClipRgn( hMetaFileDC, ClipRgn );
790 aBrushData.lbColor = RGB( 255, 255, 255 );
791 aBrushData.lbStyle = BS_SOLID;
793 FillRect( hMetaFileDC, &r, CreateBrushIndirect( &aBrushData ) );
795 ReleaseDC( 0, screen_dc );
798 aCurVP->getGLWidget()->translateBackgroundToEMF( hMetaFileDC, &aViewerCS, &aPaperCS );
802 if( aType==POST_SCRIPT )
804 QString temp = "%1 %2 %3 %4 rectclip\n\n",
805 aBuffer = temp.arg( mmLeft ).arg( mmBottom ).
806 arg( AW-mmLeft-mmRight ).arg( AH-mmBottom-mmTop );
807 //It is set clipping path
809 hFile.write( aBuffer.toLatin1() );
811 aCurVP->getGLWidget()->translateBackgroundToPS( hFile, &aViewerCS, &aPaperCS );
815 for( int i=0, n=myDrawers.count(); i<n; i++ )
816 if( aType==POST_SCRIPT )
817 result &= myDrawers[ i ]->translateToPS( hFile, &aViewerCS, &aPaperCS );
818 else if( aType==HPGL )
819 result &= myDrawers[ i ]->translateToHPGL( hFile, &aViewerCS, &aPaperCS );
821 else if( aType==ENH_METAFILE )
822 result &= myDrawers[ i ]->translateToEMF( hMetaFileDC, &aViewerCS, &aPaperCS );
825 if( aType==POST_SCRIPT || aType==HPGL )
827 insertEnding( aType, hFile);
831 else if( aType==ENH_METAFILE )
832 DeleteEnhMetaFile( CloseEnhMetaFile( hMetaFileDC ) );
840 \param theView - view to be repainted. If it is NULL then all views will be repainted
842 void GLViewer_Viewer2d::repaintView( GLViewer_ViewFrame* theView, bool makeCurrent )
844 GLViewer_ViewFrame* aCurView;
846 aCurView = (GLViewer_ViewFrame*)getActiveView();
853 ObjList anActiveObjs;
854 const ObjList& objs = myGLContext->getObjects();
855 for( ObjList::const_iterator it = objs.begin(); it != objs.end(); ++it )
857 GLViewer_Object* obj = (GLViewer_Object*)(*it);
858 if( obj->getVisible() )
859 anActiveObjs.append( obj );
865 QList<GLViewer_Drawer*>::Iterator anIt = myDrawers.begin();
866 QList<GLViewer_Drawer*>::Iterator endDIt = myDrawers.end();
867 for( ; anIt != endDIt; anIt++ )
870 QList<GLViewer_Drawer*> anActiveDrawers;
871 QList<GLViewer_Object*>::Iterator endOIt = anActiveObjs.end();
873 for( QList<GLViewer_Object*>::Iterator oit = anActiveObjs.begin(); oit != endOIt; ++oit )
875 GLViewer_Drawer* aDrawer = (*oit)->getDrawer();
878 anIt = myDrawers.begin();
880 for( ; anIt != endDIt; anIt++ )
881 if( (*anIt)->getObjectType() == (*oit)->getObjectType() )
883 (*oit)->setDrawer( *anIt );
888 if( !aDrawer ) //are not exists
890 myDrawers.append( (*oit)->createDrawer() );
891 aDrawer = (*oit)->getDrawer();
894 aDrawer->addObject( (*oit) );
895 if( anActiveDrawers.indexOf( aDrawer ) == -1 )
896 anActiveDrawers.append( aDrawer );
899 QList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
900 QList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
902 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )aCurView->getViewPort();
903 vp->getScale( xScale, yScale );
906 vp->getGLWidget()->makeCurrent();
908 for( ; aDIt != aDEndIt; aDIt++ )
909 (*aDIt)->create( xScale, yScale, false );
912 vp->getGLWidget()->swapBuffers();
914 // ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() )->getGLWidget()->makeCurrent();
918 Starts some operation on mouse event
920 void GLViewer_Viewer2d::startOperations( QMouseEvent* e )
922 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
924 float x = e->pos().x();
925 float y = e->pos().y();
927 GLViewer_Pnt point( x, y );
929 if( e->button() == Qt::LeftButton && !myGLContext->getCurrentObject() && vp->startPulling( point ) )
932 if( e->button() == Qt::LeftButton && !(vp->currentBlock() & BS_Selection) && !myGLContext->getCurrentObject() )
933 vp->startSelectByRect( e->x(), e->y() );
937 Updates started operation on mouse event
939 bool GLViewer_Viewer2d::updateOperations( QMouseEvent* e )
941 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
943 if( vp->isPulling() )
945 float x = e->pos().x();
946 float y = e->pos().y();
949 vp->drawPulling( GLViewer_Pnt( x, y ) );
954 if( !myGLContext->getCurrentObject() )
956 vp->drawSelectByRect( e->x(), e->y() );
963 Completes started operation on mouse event
965 void GLViewer_Viewer2d::finishOperations( QMouseEvent* e )
967 GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
969 if( vp->isPulling() )
976 if( !myGLContext->getCurrentObject() )
978 QRect aSelRect = vp->selectionRect();
979 vp->finishSelectByRect();
980 if ( getSelector() && !aSelRect.isNull() )
982 bool append = bool ( e->modifiers() & GLViewer_Selector::appendKey() );
983 getSelector()->select( aSelRect, append );
989 Starts some operation on mouse wheel event
991 void GLViewer_Viewer2d::startOperations( QWheelEvent* e )
993 bool zoomIn = e->delta() > 0;
995 for( myGLContext->InitSelected(); myGLContext->MoreSelected(); myGLContext->NextSelected() )
997 GLViewer_Object* anObject = myGLContext->SelectedObject();
998 update = anObject->updateZoom( zoomIn ) || update;
1001 emit wheelZoomChange( zoomIn );
1008 int GLViewer_View2dTransformer::rotateBtn = Qt::RightButton;
1013 GLViewer_View2dTransformer::GLViewer_View2dTransformer( GLViewer_Viewer* viewer, int typ )
1014 : GLViewer_ViewTransformer( viewer, typ )
1016 if ( type() == GLViewer_Viewer::Rotate )
1017 initTransform( true );
1023 GLViewer_View2dTransformer::~GLViewer_View2dTransformer()
1025 if ( type() == GLViewer_Viewer::Rotate )
1026 initTransform( false );
1030 Redefined to provide specific 3D transfomations. [ virtual public ]
1032 void GLViewer_View2dTransformer::exec()
1034 if ( !myViewer->getActiveView() )
1037 /* additional transforms */
1038 GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort();
1039 GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)vp;
1042 case GLViewer_Viewer::Rotate:
1043 myMajorBtn = rotateButton();
1044 avp->setCursor( *avp->getRotCursor() );
1047 GLViewer_ViewTransformer::exec();
1052 Handles rotation. [ protected virtual ]
1054 void GLViewer_View2dTransformer::onTransform( TransformState state )
1056 if ( !myViewer->getActiveView() )
1059 GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort();
1060 GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)vp;
1061 if ( type() == GLViewer_Viewer::Rotate )
1066 if ( myButtonState & myMajorBtn )
1067 avp->startRotation( myStart.x(), myStart.y() );
1070 if ( myButtonState & myMajorBtn )
1071 avp->rotate( myCurr.x(), myCurr.y() );
1079 GLViewer_ViewTransformer::onTransform( state );