]> SALOME platform Git repositories - modules/gui.git/blob - src/GLViewer/GLViewer_Viewer2d.cxx
Salome HOME
f98f5e2ae76818b2eb442a7073f335559ca02421
[modules/gui.git] / src / GLViewer / GLViewer_Viewer2d.cxx
1 //  Copyright (C) 2005 OPEN CASCADE
2 //
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.
7 //
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.
12 //
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
16 //
17 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
18 //
19 //  Author : OPEN CASCADE
20 //
21
22 // File:      GLViewer_Viewer2d.cxx
23 // Created:   November, 2004
24
25 /***************************************************************************
26 **  Class:   GLViewer_Viewer2d
27 **  Descr:   OpenGL Viewer 2D
28 **  Module:  GLViewer
29 **  Created: UI team, 04.09.02
30 ****************************************************************************/
31
32 //#include <GLViewerAfx.h>
33 #include "GLViewer_Viewer2d.h"
34 #include "GLViewer_Object.h"
35 #include "GLViewer_BaseObjects.h"
36 #include "GLViewer_CoordSystem.h"
37 #include "GLViewer_Context.h"
38 #include "GLViewer_Drawer.h"
39 #include "GLViewer_Selector2d.h"
40 //#include "GLViewer_Sketcher.h"
41 #include "GLViewer_ViewPort2d.h"
42
43 #include "SUIT_Desktop.h"
44 #include "SUIT_ViewWindow.h"
45
46 #include "OSD_Timer.hxx"
47 #include <TColStd_MapOfInteger.hxx>
48
49 #include <qpopupmenu.h>
50 #include <qpointarray.h>
51 #include <qcolordialog.h>
52
53 GLViewer_Viewer2d::GLViewer_Viewer2d( const QString& title) :
54 GLViewer_Viewer( title )
55 {
56     myGLContext = new GLViewer_Context( this );
57
58     //myGLSketcher = new GLViewer_Sketcher( this );
59
60     createSelector();
61
62     mySelMode = GLViewer_Viewer::Multiple;
63
64     myDrawers.clear();
65 }
66
67 GLViewer_Viewer2d::~GLViewer_Viewer2d()
68 {    
69     //myGLSketcher = 0;
70     //delete myGLSketcher;
71   GLViewer_TexFont::clearTextBases();
72 }
73
74 SUIT_ViewWindow* GLViewer_Viewer2d::createView( SUIT_Desktop* theDesktop )
75 {
76     return new GLViewer_ViewFrame( theDesktop, this );
77 }
78
79 void GLViewer_Viewer2d::addPopupItems( QPopupMenu* thePopup )
80 {
81   // CTH8434. "Change background color" menu item is available if there are no selected objects
82   if ( getSelector() == 0 || getSelector()->numSelected() == 0 )
83   {
84     if( thePopup->count() > 0 )
85         thePopup->insertSeparator();
86     thePopup->insertItem( tr( "CHANGE_BGCOLOR" ), this, SLOT( onChangeBgColor() ) );
87   }
88 }
89
90 void GLViewer_Viewer2d::onChangeBgColor()
91 {
92   if( !getActiveView() )
93     return;
94   GLViewer_ViewPort2d* vp = ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() );
95
96   QColor selColor = QColorDialog::getColor( vp->backgroundColor(), vp );        
97   if ( selColor.isValid() ) {
98     vp->setBackgroundColor( selColor );
99   }
100 }
101
102 void GLViewer_Viewer2d::updateColors( QColor colorH, QColor colorS )
103 {
104 //  cout << "GLViewer_Viewer2d::updateColors" << endl;
105
106 /*
107     for ( DrawerMap::Iterator it = myDrawers.begin(); it != myDrawers.end(); ++it )
108     {
109         it.key()->setHColor( colorH );
110         it.key()->setSColor( colorS );
111     }
112 */
113     /*
114     ObjList anObjects = myGLContext->getObjects();
115     ObjList::Iterator beginIt = anObjects.begin();
116     ObjList::Iterator endIt = anObjects.end();
117     for ( ObjList::Iterator it = beginIt; it != endIt; ++it )
118     {
119         //GLViewer_Drawer* aDrawer = (*it)->getDrawer();
120         //aDrawer->setHColor( colorH );
121         //aDrawer->setSColor( colorS );
122     }
123     */
124
125
126   activateAllDrawers( TRUE );
127 }
128
129 void GLViewer_Viewer2d::updateBorders( GLViewer_Rect* theRect )
130 {
131   QPtrVector<SUIT_ViewWindow> views = getViewManager()->getViews();
132   for ( int i = 0, n = views.count(); i < n; i++ )
133   {
134     GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
135
136     border->setLeft( QMIN( border->left(), theRect->left() ) );
137     border->setRight( QMAX( border->right(), theRect->right() ) );
138     border->setBottom( QMIN( border->bottom(), theRect->bottom() ) );
139     border->setTop( QMAX( border->top(), theRect->top() ) );
140   }
141 }
142
143 void GLViewer_Viewer2d::updateBorders()
144 {
145     QPtrVector<SUIT_ViewWindow> views = getViewManager()->getViews();
146
147     ObjList anObjects = myGLContext->getObjects();
148     ObjList::Iterator beginIt = anObjects.begin();
149     ObjList::Iterator endIt = anObjects.end();
150     for ( int i = 0, n = views.count(); i < n; i++ )
151     {
152         GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
153         if ( !border )
154           continue;
155         border->setIsEmpty( true );
156         // initialise border by default values to avoid old values
157         border->setCoords( 0, 0, 0, 0 );
158         for ( ObjList::Iterator it = beginIt; it != endIt; ++it )
159         {
160             GLViewer_Object* anObject = *it;
161             GLViewer_Rect* aRect = anObject->getRect();
162             if( !anObject->isSelectable() || !anObject->getVisible() )
163                 continue;
164
165             if( border->isEmpty() )
166             {
167                 border->setIsEmpty( false );
168                 border->setCoords( aRect->left(), aRect->right(), aRect->bottom(), aRect->top() );
169             }
170             else
171             {
172                 border->setLeft( QMIN( border->left(), aRect->left() ) );
173                 border->setRight( QMAX( border->right(), aRect->right() ) );
174                 border->setBottom( QMIN( border->bottom(), aRect->bottom() ) );
175                 border->setTop( QMAX( border->top(), aRect->top() ) );
176             }
177         }
178     }
179 }
180
181 void GLViewer_Viewer2d::updateAll()
182 {
183   if ( !getActiveView() )
184     return;
185
186   QPtrVector<SUIT_ViewWindow> views = getViewManager()->getViews();
187   for ( int i = 0, n = views.count(); i < n; i++ )
188     ( ( GLViewer_ViewPort2d* )( ( GLViewer_ViewFrame* )views[i] )->getViewPort() )->getGLWidget()->updateGL();
189 }
190
191 void GLViewer_Viewer2d::updateDrawers( GLboolean update, GLfloat scX, GLfloat scY )
192 {
193 //  cout << "GLViewer_Viewer2d::updateDrawers" << endl;
194
195     //myGLContext->updateScales( scX, scY );
196     //myGLSketcher->drawContour();
197     activateAllDrawers( update );
198 }
199
200 void GLViewer_Viewer2d::activateDrawers( QValueList<GLViewer_Object*>& theObjects, bool onlyUpdate, GLboolean swap )
201 {
202     //cout << "GLViewer_Viewer2d::activateDrawers " << (int)onlyUpdate << " " << (int)swap << endl;
203     QValueList<GLViewer_Drawer*>::Iterator anIt = myDrawers.begin();
204     QValueList<GLViewer_Drawer*>::Iterator endDIt = myDrawers.end();
205     for( ; anIt != endDIt; anIt++ )
206         (*anIt)->clear();
207
208     QValueList<GLViewer_Drawer*> anActiveDrawers;
209     QValueList<GLViewer_Object*>::Iterator endOIt = theObjects.end();
210
211     for( QValueList<GLViewer_Object*>::Iterator oit = theObjects.begin(); oit != endOIt; ++oit )
212     {
213         GLViewer_Drawer* aDrawer = (*oit)->getDrawer();
214         if( !aDrawer )
215         {
216             anIt = myDrawers.begin();
217             endDIt = myDrawers.end();
218
219             for( ; anIt != endDIt; anIt++ )
220                 if( (*anIt)->getObjectType() == (*oit)->getObjectType() )
221                 {
222                     (*oit)->setDrawer( *anIt );
223                     aDrawer = *anIt;
224                     break;
225                 }
226
227             if( !aDrawer )
228             {
229                 myDrawers.append( (*oit)->createDrawer() );
230                 aDrawer = (*oit)->getDrawer();
231             }
232         }
233         if ( !aDrawer )
234           continue;
235         aDrawer->addObject( (*oit) );
236
237         int aPriority = aDrawer->getPriority();
238
239         if( anActiveDrawers.findIndex( aDrawer ) != -1 )
240             continue;
241
242         QValueList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
243         QValueList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
244         for( ; aDIt != aDEndIt; ++aDIt )
245             if( (*aDIt)->getPriority() > aPriority )
246                 break;
247
248         anActiveDrawers.insert( aDIt, aDrawer );
249     } 
250
251     QValueList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
252     QValueList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
253
254     QPtrVector<SUIT_ViewWindow> views = getViewManager()->getViews();
255     for ( int i = 0, n = views.count(); i < n; i++ )
256     {
257         float xScale, yScale;
258         GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort();
259         vp->getScale( xScale, yScale );
260         vp->getGLWidget()->makeCurrent();
261
262         for( ; aDIt != aDEndIt; aDIt++ )
263         {
264             GLViewer_Drawer* aDrawer = *aDIt;
265             if( aDrawer )
266                 aDrawer->create( xScale, yScale, onlyUpdate );
267         }
268 /*
269         // draw border
270         GLViewer_Rect* border = ( ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)views[i])->getViewPort() )->getBorder();
271         (*aDIt)->drawRectangle( border, Qt::blue );
272
273         QString coords = QString::number( border->left() ) + " " + QString::number( border->right() ) + " " +
274                          QString::number( border->bottom() ) + " " + QString::number( border->top() );
275         (*aDIt)->drawText( "Border : " + coords, border->left(), border->top() + 10 / yScale,
276                            Qt::blue, &QFont( "Courier", 8, QFont::Normal ), 2 );
277 */
278         if ( swap )
279            vp->getGLWidget()->swapBuffers();
280     }
281
282     ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() )->getGLWidget()->makeCurrent();
283 }
284
285 void GLViewer_Viewer2d::activateDrawer( GLViewer_Object* theObject, bool onlyUpdate, GLboolean swap )
286 {
287   ObjList aList;
288   aList.append( theObject );
289   activateDrawers( aList, onlyUpdate, swap );
290 }
291
292 void GLViewer_Viewer2d::activateAllDrawers( bool onlyUpdate, GLboolean swap )
293 {
294     if ( !getActiveView() )
295       return;
296
297     ObjList anActiveObjs;
298     const ObjList& objs = myGLContext->getObjects();
299     for( ObjList::const_iterator it = objs.begin(); it != objs.end(); ++it )
300     {
301       GLViewer_Object* obj = (GLViewer_Object*)(*it);
302       if( obj->getVisible() )
303           anActiveObjs.append( obj );
304     }
305
306     activateDrawers( anActiveObjs, onlyUpdate, swap );
307 }
308
309 void GLViewer_Viewer2d::onCreateGLMarkers( int theMarkersNum, int theMarkersRad )
310 {
311     if ( !getActiveView() )
312       return;
313
314     GLViewer_MarkerSet* aMarkerSet = new GLViewer_MarkerSet( theMarkersNum, theMarkersRad );
315     getGLContext()->insertObject( aMarkerSet );
316
317     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
318     int vpWidth = vp->getWidth();
319     int vpHeight = vp->getHeight();
320
321     float* aXCoord = new float[ theMarkersNum ];
322     float* anYCoord = new float[ theMarkersNum ];
323
324     srand( 1 );
325     for ( long i = 0; i < theMarkersNum; i++ )  
326     {
327         aXCoord[i] = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
328         anYCoord[i] = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
329     }
330
331     aMarkerSet->setXCoord( aXCoord, theMarkersNum );
332     aMarkerSet->setYCoord( anYCoord, theMarkersNum );
333     aMarkerSet->compute();
334
335     updateBorders( aMarkerSet->getRect() );
336     
337     activateAllDrawers( false );
338     activateTransform( GLViewer_Viewer::FitAll );
339
340     delete[] aXCoord;
341     delete[] anYCoord;
342 }
343
344 void GLViewer_Viewer2d::onCreateGLPolyline( int theAnglesNum, int theRadius, int thePolylineNumber )
345 {
346     if ( !getActiveView() )
347       return;
348
349     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
350     int vpWidth = vp->getWidth();
351     int vpHeight = vp->getHeight();
352
353     float* aXCoord = new float[ theAnglesNum ];
354     float* anYCoord = new float[ theAnglesNum ];
355
356     //srand( ( unsigned )time( NULL ) );
357     srand( 1 );
358     for( int j = 0; j < thePolylineNumber; j++)
359     {
360         GLViewer_Polyline* aPolyline = new GLViewer_Polyline( theAnglesNum, theRadius );
361         getGLContext()->insertObject( aPolyline );
362
363         float aXOffset = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
364         float anYOffset = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
365         for( int i = 0; i < theAnglesNum; i++ )  
366         {
367             aXCoord[i] = cos( 2. * PI * i / theAnglesNum ) * theRadius + aXOffset;
368             anYCoord[i] = sin( 2. * PI * i / theAnglesNum ) * theRadius + anYOffset;
369         }
370
371         aPolyline->setHighSelAll( true );
372         aPolyline->setClosed( true );
373         aPolyline->setXCoord( aXCoord, theAnglesNum );
374         aPolyline->setYCoord( anYCoord, theAnglesNum );
375         aPolyline->compute();
376
377         updateBorders( aPolyline->getRect() );
378     }
379     
380     activateAllDrawers( false );
381     activateTransform( GLViewer_Viewer::FitAll );
382
383     delete[] aXCoord;
384     delete[] anYCoord;
385 }
386
387 void GLViewer_Viewer2d::onCreateGLText( QString theStr, int theTextNumber )
388 {
389     if ( !getActiveView() )
390       return;
391
392     if( theTextNumber <= 0 )
393         return;
394     
395     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
396     int vpWidth = vp->getWidth();
397     int vpHeight = vp->getHeight();
398
399     //srand( ( unsigned )time( NULL ) );
400     srand( 1 );
401     for( int j = 0; j < theTextNumber; j++)
402     {
403         float aXPos = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpWidth / 2.);
404         float anYPos = cos( PI * (rand() / (GLfloat)RAND_MAX) ) * ((GLfloat)vpHeight / 2.);
405         QColor aColor( 255, 0, 255 );
406
407         GLViewer_TextObject* aText = new GLViewer_TextObject( theStr, aXPos, anYPos, aColor  );
408         aText->compute();
409         getGLContext()->insertObject( aText );
410
411         updateBorders( aText->getRect() );
412     }
413
414     activateAllDrawers( false );
415 }
416
417 void GLViewer_Viewer2d::transPoint( GLfloat& x, GLfloat& y )
418 {
419     if ( !getActiveView() )
420       return;
421
422     GLfloat xScale, yScale;
423     GLfloat xPan, yPan;
424
425     GLViewer_ViewPort2d* curvp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
426
427     curvp->getScale( xScale, yScale );
428     curvp->getPan( xPan, yPan );
429
430     GLfloat a = curvp->getGLWidget()->getRotationAngle() * PI / 180.;
431     
432     x = (  x - ( GLfloat )curvp->getWidth()  / 2 ) / xScale;
433     y = ( -y + ( GLfloat )curvp->getHeight() / 2 ) / yScale;
434
435     GLfloat x1 = x;
436     GLfloat y1 = y;
437
438     x = x1 * cos(a) + y1 * sin(a);
439     y = -x1 * sin(a) + y1 * cos(a);
440
441     x -= xPan;
442     y -= yPan;
443 }
444
445 QRect* GLViewer_Viewer2d::getWinObjectRect( GLViewer_Object* theObject )
446 {
447     if ( !getActiveView() )
448       return 0;
449
450     GLfloat xScale, yScale;
451     GLfloat xPan, yPan;
452
453     GLViewer_ViewPort2d* curvp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
454     GLfloat aWidth = curvp->getWidth();
455     GLfloat aHeight = curvp->getHeight();
456
457
458     curvp->getScale( xScale, yScale );
459     curvp->getPan( xPan, yPan );
460
461     QRect aObjRect = theObject->getRect()->toQRect();
462     float aLeft = aObjRect.left() + xPan, aRight = aObjRect.right() + xPan;
463     float aTop = aObjRect.top() + yPan, aBot = aObjRect.bottom() + yPan;
464
465     GLfloat anAngle = curvp->getGLWidget()->getRotationAngle() * PI / 180.;
466
467     QPointArray aPointArray(4);
468     aPointArray[0] = QPoint( (int)(aLeft*cos(anAngle) - aTop*sin(anAngle)),
469                              (int)(aLeft*sin(anAngle) + aTop*cos(anAngle)) );
470     aPointArray[1] = QPoint( (int)(aRight*cos(anAngle) - aTop*sin(anAngle)),
471                              (int)(aRight*sin(anAngle) + aTop*cos(anAngle)) );
472     aPointArray[2] = QPoint( (int)(aRight*cos(anAngle) - aBot*sin(anAngle)),
473                              (int)(aRight*sin(anAngle) + aBot*cos(anAngle)) );
474     aPointArray[3] = QPoint( (int)(aLeft*cos(anAngle) - aBot*sin(anAngle)),
475                              (int)(aLeft*sin(anAngle) + aBot*cos(anAngle)) );
476
477     int aMinLeft = aPointArray[0].x(), aMaxRight = aPointArray[0].x(), 
478         aMinTop = aPointArray[0].y(), aMaxBottom = aPointArray[0].y();
479     for( int i = 1; i < 4; i++ )
480     {
481         int x = aPointArray[i].x();
482         int y = aPointArray[i].y();
483         aMinLeft = QMIN( aMinLeft,x );
484         aMaxRight = QMAX( aMaxRight, x );
485         aMinTop = QMIN( aMinTop, y );
486         aMaxBottom = QMAX( aMaxBottom, y );
487     }
488
489     aLeft = (aMinLeft/* + xPan*/)*xScale + aWidth / 2;
490     aRight = (aMaxRight/* + xPan*/)*xScale + aWidth / 2;
491
492     aTop = -( (aMaxBottom/* + yPan*/)*yScale - aHeight / 2 );
493     aBot = -( (aMinTop/* + yPan*/)*yScale - aHeight / 2 );    
494
495     QRect* newRect = new QRect( (int)aLeft, (int)aTop, (int)(aRight-aLeft), (int)(aBot-aTop) );
496     
497     return newRect;
498 }
499
500 GLViewer_Rect GLViewer_Viewer2d::getGLVRect( const QRect& theRect ) const
501 {
502   if ( !getActiveView() )
503       return GLViewer_Rect();
504
505   GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
506
507   if( !vp )
508     return GLViewer_Rect();
509
510   return vp->win2GLV( theRect );
511 }
512
513 QRect GLViewer_Viewer2d::getQRect( const GLViewer_Rect& theRect ) const
514 {
515   if ( !getActiveView() )
516       return QRect();
517
518   GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort();
519
520   if( !vp )
521     return QRect();
522
523   return vp->GLV2win( theRect );
524 }
525
526 GLViewer_Selector* GLViewer_Viewer2d::createSelector()
527 {
528   return new GLViewer_Selector2d( this, getGLContext() );
529 }
530
531 GLViewer_ViewTransformer* GLViewer_Viewer2d::createTransformer( int type )
532 {
533     return new GLViewer_View2dTransformer( this, type );
534 }
535 /*
536 GLViewer_Sketcher* GLViewer_Viewer2d::createGLSketcher( int type )
537 {
538     return new GLViewer_Sketcher( this, type );
539 }
540
541 void GLViewer_Viewer2d::activateGLSketching( int type )
542 {
543     GLViewer_ViewPort2d* vp = 0;
544     if ( !getActiveView() || !( vp = ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() ) )
545         return;
546
547     // Finish current sketching
548     if ( type == None )
549     {
550         if ( myGLSketcher->getType() != None )
551         {
552             myGLSketcher->setType( None );
553             finishSketching();
554         }
555     }
556     // Activate new sketching
557     else
558     {
559         activateGLSketching( None );  // concurrency not supported
560         myGLSketcher->setType( type );
561         startSketching();
562     }
563 }
564
565 void GLViewer_Viewer2d::startSketching()
566 {
567     GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)getActiveView()->getViewPort();
568     avp->setCursor( *avp->getSketchCursor() );
569     //avp->enablePopup( false );
570     myGLSketcher->startSketching();
571 }
572
573 void GLViewer_Viewer2d::finishSketching()
574 {
575     GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)getActiveView()->getViewPort();
576     avp->setCursor( *avp->getDefaultCursor() );
577     //avp->enablePopup( true );
578     myGLSketcher->finishSketching();
579 }
580
581 bool GLViewer_Viewer2d::isSketchingActive()
582 {
583     return myGLSketcher->getType() != None; 
584 }
585
586 int GLViewer_Viewer2d::getSketchingType()
587 {
588     return myGLSketcher->getType();
589 }
590
591 void GLViewer_Viewer2d::onSketchDelObject()
592 {
593     GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)getActiveView()->getViewPort();
594     avp->setCursor( *avp->getDefaultCursor() );    
595     myGLSketcher->finishSketching( true );
596 }
597
598 void GLViewer_Viewer2d::onSketchUndoLast()
599 {
600
601 }
602
603 void GLViewer_Viewer2d::onSketchFinish()
604 {
605     finishSketching();
606 }
607 */
608 void GLViewer_Viewer2d::onMouseEvent( SUIT_ViewWindow*, QMouseEvent* e )
609 {
610     if ( !getActiveView() )
611         return;
612
613     //if ( testRotation( e ) )
614     //    return;
615
616     switch( e->type() )
617     {
618         case QEvent::MouseButtonPress :
619         case QEvent::MouseMove :
620         case QEvent::MouseButtonRelease :
621             //if( myGLSketcher->getType() != None )
622             //    myGLSketcher->sketch( e );
623         default: break;
624     }
625
626     GLViewer_Viewer::onMouseEvent( 0, e );
627 }
628
629 bool GLViewer_Viewer2d::testRotation( QMouseEvent* e )
630 {
631     if ( ( e->button() == GLViewer_View2dTransformer::rotateButton() ) &&
632          ( e->type() == QEvent::MouseButtonPress ) &&
633          ( e->state() & GLViewer_ViewTransformer::accelKey() ) )
634     {
635         activateTransform( GLViewer_Viewer::Rotate );
636         return true;
637     }
638     return false;
639 }
640
641
642 void GLViewer_Viewer2d::insertHeader( VectorFileType aType, QFile& hFile )
643 {
644     if( aType == POST_SCRIPT )
645     {
646         QString header = "%!PS-Adobe-3.0\n";
647         header += "%%Creator: OpenCascade 2004\n";
648         header += "%%Title: Our document\n";        
649         header += "%%PageOrder: Ascend\n";      
650         header += "%%Orientation: Portrait\n";
651         header += "%%LanguageLevel: 2\n";
652
653         header += "%%Pages: 1\n";
654         header += "%%Page: 1\n\n";
655         
656         hFile.writeBlock( header.ascii(), header.length() );
657     }
658     else if( aType == HPGL )
659     {
660         QString header = "[Esc].(;\n";
661         header += "[Esc].I81;;17:\n";
662         header += "[Esc].N;19:\n";
663         header += "IN;\n";
664         header += "SC;\n";
665         header += "PU;\n";
666         header += "SP1;\n";
667         header += "LT;\n";
668         header += "VS36;\n";
669         
670         hFile.writeBlock( header.ascii(), header.length() );
671     }
672 }
673
674 void GLViewer_Viewer2d::insertEnding( VectorFileType aType, QFile& hFile )
675 {
676     if( aType == POST_SCRIPT )
677     {
678         QString ending = "showpage\n\n%%EOF";
679         hFile.writeBlock( ending.ascii(), ending.length() );
680     }
681     else if( aType == HPGL )
682     {
683         QString ending = "PU;PA0,0;SP;EC;PG1;EC1;OE\n"; 
684         hFile.writeBlock( ending.ascii(), ending.length() );
685     }
686 }
687
688 inline void mm2custom( GLViewer_Viewer2d::VectorFileType aType, double& value )
689 {
690     if( aType==GLViewer_Viewer2d::POST_SCRIPT )
691         value*=2.8346; //mm to pt
692
693     else if( aType==GLViewer_Viewer2d::HPGL )
694         value*=40;     //mm to plu (there are 40 plues in mm)
695 #ifdef WIN32
696     else if( aType==GLViewer_Viewer2d::ENH_METAFILE )
697         value*=100;    //this unit is 1/100 mm
698 #endif 
699 }
700
701 bool GLViewer_Viewer2d::translateTo( VectorFileType aType, QString FileName, PaperType aPType, 
702                                   double mmLeft, double mmRight, double mmTop, double mmBottom )
703 {
704     if ( !getActiveView() )
705       return false;
706
707         QFile hFile( FileName.ascii() );
708
709 #ifdef WIN32
710     HDC hMetaFileDC;
711 #endif
712
713     GLViewer_ViewPort2d* aCurVP = (GLViewer_ViewPort2d*) getActiveView()->getViewPort();
714
715     GLfloat xPan, yPan;
716     aCurVP->getPan( xPan, yPan );
717     GLfloat aRotation = aCurVP->getGLWidget()->getRotationAngle() * 3.14159265 / 180.0;
718
719     GLViewer_CoordSystem aViewerCS( GLViewer_CoordSystem::Cartesian, xPan, yPan, 1.0, 1.0, aRotation );
720
721     double AW = Sizes[2*int(aPType)], 
722            AH = Sizes[2*int(aPType)+1]; //size of Axx paper in mm
723
724     mm2custom( aType, mmLeft ); //we translate mm to custom units
725     mm2custom( aType, mmRight );
726     mm2custom( aType, mmTop );
727     mm2custom( aType, mmBottom );
728     mm2custom( aType, AW );
729     mm2custom( aType, AH );
730
731     float xScale, yScale;
732     aCurVP->getScale( xScale, yScale );
733
734     double VPWidth = aCurVP->getWidth()/xScale,   //the width in reference units
735            VPHeight = aCurVP->getHeight()/yScale;
736
737     double k1 = ( AW-mmLeft-mmRight ) / VPWidth,
738            k2 = ( AH-mmTop-mmBottom ) / VPHeight;
739
740     if( k1>k2 )
741         k1 = k2; //We select the minimum
742
743     double hdelta = ( AW-mmLeft-mmRight - VPWidth * k1 )/2.0, //addition in horizontal
744            vdelta = ( AH-mmTop-mmBottom - VPHeight * k1 )/2.0; //addition in vertical
745
746     mmLeft   += hdelta; //The real free space on the left and right borders
747     mmRight  += hdelta;
748     mmTop    += vdelta;
749     mmBottom += vdelta;
750
751     GLViewer_CoordSystem aPaperCS( GLViewer_CoordSystem::Cartesian, 
752         -(mmLeft/k1+VPWidth/2.0), -(mmBottom/k1+VPHeight/2.0), 1/k1, 1/k1 );
753
754     if( aType==POST_SCRIPT || aType==HPGL )
755     {
756         hFile.open( IO_ReadWrite | IO_Truncate );
757         hFile.at( 0 );
758         insertHeader( aType, hFile );
759     }
760 #ifdef WIN32
761     else if( aType==ENH_METAFILE )
762     {
763         RECT r; 
764         r.left = 0; r.right = AW; 
765         r.top = 0; r.bottom = AH; 
766         HDC screen_dc = GetDC( 0 ); //The screen device context
767         HDC bitDC = CreateCompatibleDC ( screen_dc ); //The context compatible with screen
768
769         hMetaFileDC = CreateEnhMetaFile( bitDC, FileName.ascii(), &r, "" );
770         SetMapMode( hMetaFileDC, MM_HIMETRIC );
771         SetWindowOrgEx( hMetaFileDC, 0, r.bottom, NULL );
772         HRGN ClipRgn = CreateRectRgn( 0, 0, AW, AH );
773         SelectClipRgn( hMetaFileDC, ClipRgn );
774
775         LOGBRUSH aBrushData;
776         aBrushData.lbColor = RGB( 255, 255, 255 );      
777         aBrushData.lbStyle = BS_SOLID;
778
779         FillRect( hMetaFileDC, &r, CreateBrushIndirect( &aBrushData ) );
780
781         ReleaseDC( 0, screen_dc );
782         DeleteDC( bitDC );
783
784         aCurVP->getGLWidget()->translateBackgroundToEMF( hMetaFileDC, &aViewerCS, &aPaperCS );
785     }
786 #endif
787
788     if( aType==POST_SCRIPT )
789     {
790         QString temp = "%1 %2 %3 %4 rectclip\n\n",
791                 aBuffer = temp.arg( mmLeft ).arg( mmBottom ).
792                                arg( AW-mmLeft-mmRight ).arg( AH-mmBottom-mmTop );
793         //It is set clipping path
794
795         hFile.writeBlock( aBuffer.ascii(), aBuffer.length() );
796
797         aCurVP->getGLWidget()->translateBackgroundToPS( hFile, &aViewerCS, &aPaperCS );
798     }
799
800     bool result = true;
801     for( int i=0, n=myDrawers.count(); i<n; i++ )
802         if( aType==POST_SCRIPT )
803             result &= myDrawers[ i ]->translateToPS( hFile, &aViewerCS, &aPaperCS );
804         else if( aType==HPGL )
805             result &= myDrawers[ i ]->translateToHPGL( hFile, &aViewerCS, &aPaperCS );
806 #ifdef WIN32
807         else if( aType==ENH_METAFILE )
808             result &= myDrawers[ i ]->translateToEMF( hMetaFileDC, &aViewerCS, &aPaperCS );
809 #endif
810
811     if( aType==POST_SCRIPT || aType==HPGL )
812     {
813         insertEnding( aType, hFile);
814         hFile.close();
815     }
816 #ifdef WIN32
817     else if( aType==ENH_METAFILE )  
818         DeleteEnhMetaFile( CloseEnhMetaFile( hMetaFileDC ) );
819 #endif
820
821     return true;
822 }
823
824
825 void GLViewer_Viewer2d::repaintView( GLViewer_ViewFrame* theView, bool makeCurrent )
826 {
827     GLViewer_ViewFrame* aCurView;
828     if( !theView )
829         aCurView = (GLViewer_ViewFrame*)getActiveView();
830     else
831         aCurView = theView;
832     
833     if ( !aCurView )
834       return;
835
836     ObjList anActiveObjs;
837     const ObjList& objs = myGLContext->getObjects();
838     for( ObjList::const_iterator it = objs.begin(); it != objs.end(); ++it )
839     {
840       GLViewer_Object* obj = (GLViewer_Object*)(*it);
841       if( obj->getVisible() )
842           anActiveObjs.append( obj );
843     }
844
845     float xScale;
846     float yScale;
847
848     QValueList<GLViewer_Drawer*>::Iterator anIt = myDrawers.begin();
849     QValueList<GLViewer_Drawer*>::Iterator endDIt = myDrawers.end();
850     for( ; anIt != endDIt; anIt++ )
851             (*anIt)->clear();
852
853     QValueList<GLViewer_Drawer*> anActiveDrawers;
854     QValueList<GLViewer_Object*>::Iterator endOIt = anActiveObjs.end();
855
856     for( QValueList<GLViewer_Object*>::Iterator oit = anActiveObjs.begin(); oit != endOIt; ++oit )
857     {
858         GLViewer_Drawer* aDrawer = (*oit)->getDrawer();
859         if( !aDrawer )
860         {
861             anIt = myDrawers.begin();            
862
863             for( ; anIt != endDIt; anIt++ )
864                 if( (*anIt)->getObjectType() == (*oit)->getObjectType() )
865                 {
866                     (*oit)->setDrawer( *anIt );
867                     aDrawer = *anIt;
868                     break;
869                 }
870
871             if( !aDrawer ) //are not exists
872             {
873                 myDrawers.append( (*oit)->createDrawer() );
874                 aDrawer = (*oit)->getDrawer();
875             }
876         }
877         aDrawer->addObject( (*oit) );
878         if( anActiveDrawers.findIndex( aDrawer ) == -1 )
879             anActiveDrawers.append( aDrawer );
880     } 
881
882     QValueList<GLViewer_Drawer*>::Iterator aDIt = anActiveDrawers.begin();
883     QValueList<GLViewer_Drawer*>::Iterator aDEndIt = anActiveDrawers.end();
884
885     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )aCurView->getViewPort();
886     vp->getScale( xScale, yScale );
887
888     if( makeCurrent )
889         vp->getGLWidget()->makeCurrent();
890
891     for( ; aDIt != aDEndIt; aDIt++ )
892         (*aDIt)->create( xScale, yScale, false );
893     
894 //    if ( swap )
895     vp->getGLWidget()->swapBuffers();
896
897 //    ( ( GLViewer_ViewPort2d* )getActiveView()->getViewPort() )->getGLWidget()->makeCurrent();
898 }
899
900 void GLViewer_Viewer2d::startOperations( QMouseEvent* e )
901 {
902     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
903
904     float x = e->pos().x();
905     float y = e->pos().y();
906     transPoint( x, y );
907     GLViewer_Pnt point( x, y );
908
909     if( e->button() == Qt::LeftButton && !myGLContext->getCurrentObject() && vp->startPulling( point ) )
910         return;
911
912     if( e->button() == Qt::LeftButton && !(vp->currentBlock() & BS_Selection) && !myGLContext->getCurrentObject() )
913         vp->startSelectByRect( e->x(), e->y() );
914 }
915
916 bool GLViewer_Viewer2d::updateOperations( QMouseEvent* e )
917 {
918     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
919
920     if( vp->isPulling() )
921     {
922         float x = e->pos().x();
923         float y = e->pos().y();
924         transPoint( x, y );
925
926         vp->drawPulling( GLViewer_Pnt( x, y ) );
927         updateAll();
928         return true;
929     }
930
931     if( !myGLContext->getCurrentObject() )
932     {
933         vp->drawSelectByRect( e->x(), e->y() );
934         return true;
935     }
936     return false;
937 }
938
939 void GLViewer_Viewer2d::finishOperations( QMouseEvent* e )
940 {
941     GLViewer_ViewPort2d* vp = ( GLViewer_ViewPort2d* )((GLViewer_ViewFrame*)getActiveView())->getViewPort();
942
943     if( vp->isPulling() )
944     {
945         vp->finishPulling();
946         updateAll();
947         return;
948     }
949
950     if( !myGLContext->getCurrentObject() )
951     {
952         QRect aSelRect = vp->selectionRect();
953         vp->finishSelectByRect();
954         if ( getSelector() && !aSelRect.isNull() )
955         {            
956             bool append = bool ( e->state() & GLViewer_Selector::appendKey() );
957             getSelector()->select( aSelRect, append );
958         }
959     }
960 }
961
962 void GLViewer_Viewer2d::startOperations( QWheelEvent* e )
963 {
964     bool zoomIn = e->delta() > 0;
965     bool update = false;
966     for( myGLContext->InitSelected(); myGLContext->MoreSelected(); myGLContext->NextSelected() )
967     {
968         GLViewer_Object* anObject = myGLContext->SelectedObject();
969         update = anObject->updateZoom( zoomIn ) || update;
970     }
971
972     emit wheelZoomChange( zoomIn );
973
974     if( update )
975         updateAll();
976 }
977
978
979 /****************************************************************
980 **  Class: GLViewer_View2dTransformer
981 **
982 *****************************************************************/
983
984 int GLViewer_View2dTransformer::rotateBtn = RightButton;
985
986 GLViewer_View2dTransformer::GLViewer_View2dTransformer( GLViewer_Viewer* viewer, int typ )
987 : GLViewer_ViewTransformer( viewer, typ )
988 {
989     if ( type() == GLViewer_Viewer::Rotate )
990         initTransform( true );
991 }
992
993 GLViewer_View2dTransformer::~GLViewer_View2dTransformer()
994 {
995     if ( type() == GLViewer_Viewer::Rotate )
996         initTransform( false );
997 }
998
999 /*!
1000     Redefined to provide specific 3D transfomations. [ virtual public ]
1001 */
1002 void GLViewer_View2dTransformer::exec()
1003 {
1004     if ( !myViewer->getActiveView() )
1005       return;
1006
1007     /* additional transforms */
1008     GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort();
1009     GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)vp;
1010     switch ( myType )
1011     {
1012         case GLViewer_Viewer::Rotate:
1013             myMajorBtn = rotateButton();
1014             avp->setCursor( *avp->getRotCursor() );
1015             break;
1016         default:
1017             GLViewer_ViewTransformer::exec();
1018     }
1019 }
1020
1021 /*!
1022     Handles rotation. [ protected virtual ]
1023 */
1024 void GLViewer_View2dTransformer::onTransform( TransformState state )
1025 {
1026     if ( !myViewer->getActiveView() )
1027       return;
1028
1029     GLViewer_ViewPort* vp = myViewer->getActiveView()->getViewPort();
1030     GLViewer_ViewPort2d* avp = (GLViewer_ViewPort2d*)vp;
1031     if ( type() == GLViewer_Viewer::Rotate )
1032     {
1033         switch ( state )
1034         {
1035             case Debut:
1036                 if ( myButtonState & myMajorBtn )
1037                     avp->startRotation( myStart.x(), myStart.y() );
1038                 break;
1039             case EnTrain:
1040                 if ( myButtonState & myMajorBtn )
1041                     avp->rotate( myCurr.x(), myCurr.y() );
1042                 break;
1043             case Fin:
1044                 avp->endRotation();
1045                 break;
1046             default: break;
1047         }
1048     }
1049     GLViewer_ViewTransformer::onTransform( state );
1050 }