718bc4486484769ae5235df00863a66509170ad3
[occt.git] / samples / qt / Common / src / View.cxx
1 #if !defined _WIN32
2 #define QT_CLEAN_NAMESPACE         /* avoid definition of INT32 and INT8 */
3 #endif
4
5 #include "View.h"
6 #include "ApplicationCommon.h"
7
8 #include <Standard_WarningsDisable.hxx>
9 #include <QApplication>
10 #include <QPainter>
11 #include <QMenu>
12 #include <QColorDialog>
13 #include <QCursor>
14 #include <QFileInfo>
15 #include <QFileDialog>
16 #include <QMouseEvent>
17 #include <QRubberBand>
18 #include <QMdiSubWindow>
19 #include <QStyleFactory>
20 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && QT_VERSION < 0x050000
21   #include <QX11Info>
22 #endif
23 #include <Standard_WarningsRestore.hxx>
24
25
26 #include <Graphic3d_ExportFormat.hxx>
27 #include <Graphic3d_GraphicDriver.hxx>
28 #include <Graphic3d_TextureEnv.hxx>
29
30 #include <OcctWindow.h>
31 #include <Aspect_DisplayConnection.hxx>
32
33 // the key for multi selection :
34 #define MULTISELECTIONKEY Qt::ShiftModifier
35
36 // the key for shortcut ( use to activate dynamic rotation, panning )
37 #define CASCADESHORTCUTKEY Qt::ControlModifier
38
39 // for elastic bean selection
40 #define ValZWMin 1
41
42 static QCursor* defCursor     = NULL;
43 static QCursor* handCursor    = NULL;
44 static QCursor* panCursor     = NULL;
45 static QCursor* globPanCursor = NULL;
46 static QCursor* zoomCursor    = NULL;
47 static QCursor* rotCursor     = NULL;
48
49 View::View( Handle(AIS_InteractiveContext) theContext, QWidget* parent )
50 : QWidget( parent ),
51   myIsRaytracing( false ),
52   myIsShadowsEnabled (true),
53   myIsReflectionsEnabled (false),
54   myIsAntialiasingEnabled (false),
55   myViewActions( 0 ),
56   myRaytraceActions( 0 ),
57   myBackMenu( NULL )
58 {
59 #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && QT_VERSION < 0x050000
60   XSynchronize(x11Info().display(),true);
61 #endif
62   myContext = theContext;
63
64   myXmin = 0;
65   myYmin = 0;
66   myXmax = 0;
67   myYmax = 0;
68   myCurZoom = 0;
69   myRectBand = 0;
70
71   setAttribute(Qt::WA_PaintOnScreen);
72   setAttribute(Qt::WA_NoSystemBackground);
73
74   myCurrentMode = CurAction3d_Nothing;
75   myHlrModeIsOn = Standard_False;
76   setMouseTracking( true );
77
78   initViewActions();
79   initCursors();
80
81   setBackgroundRole( QPalette::NoRole );//NoBackground );
82   // set focus policy to threat QContextMenuEvent from keyboard  
83   setFocusPolicy( Qt::StrongFocus );
84   setAttribute( Qt::WA_PaintOnScreen );
85   setAttribute( Qt::WA_NoSystemBackground );
86   init();
87 }
88
89 View::~View()
90 {
91   delete myBackMenu;
92 }
93
94 void View::init()
95 {
96   if ( myView.IsNull() )
97     myView = myContext->CurrentViewer()->CreateView();
98
99   Handle(OcctWindow) hWnd = new OcctWindow ( this );
100   myView->SetWindow (hWnd);
101   if ( !hWnd->IsMapped() )
102   {
103     hWnd->Map();
104   }
105   myView->SetBackgroundColor (Quantity_NOC_BLACK);
106   myView->MustBeResized();
107
108   if (myIsRaytracing)
109     myView->ChangeRenderingParams().Method = Graphic3d_RM_RAYTRACING;
110 }
111
112 void View::paintEvent( QPaintEvent *  )
113 {
114 //  QApplication::syncX();
115   myView->Redraw();
116 }
117
118 void View::resizeEvent( QResizeEvent * )
119 {
120 //  QApplication::syncX();
121   if( !myView.IsNull() )
122   {
123     myView->MustBeResized();
124   }
125 }
126
127 void View::fitAll()
128 {
129   myView->FitAll();
130   myView->ZFitAll();
131   myView->Redraw();
132 }
133
134 void View::fitArea()
135 {
136   myCurrentMode = CurAction3d_WindowZooming;
137 }
138
139 void View::zoom()
140 {
141   myCurrentMode = CurAction3d_DynamicZooming;
142 }
143
144 void View::pan()
145 {
146   myCurrentMode = CurAction3d_DynamicPanning;
147 }
148
149 void View::rotation()
150 {
151   myCurrentMode = CurAction3d_DynamicRotation;
152 }
153
154 void View::globalPan()
155 {
156   // save the current zoom value
157   myCurZoom = myView->Scale();
158   // Do a Global Zoom
159   myView->FitAll();
160   // Set the mode
161   myCurrentMode = CurAction3d_GlobalPanning;
162 }
163
164 void View::front()
165 {
166   myView->SetProj( V3d_Yneg );
167 }
168
169 void View::back()
170 {
171   myView->SetProj( V3d_Ypos );
172 }
173
174 void View::top()
175 {
176   myView->SetProj( V3d_Zpos );
177 }
178
179 void View::bottom()
180 {
181   myView->SetProj( V3d_Zneg );
182 }
183
184 void View::left()
185 {
186   myView->SetProj( V3d_Xneg );
187 }
188
189 void View::right()
190 {
191   myView->SetProj( V3d_Xpos );
192 }
193
194 void View::axo()
195 {
196   myView->SetProj( V3d_XposYnegZpos );
197 }
198
199 void View::reset()
200 {
201   myView->Reset();
202 }
203
204 void View::hlrOff()
205 {
206   QApplication::setOverrideCursor( Qt::WaitCursor );
207   myHlrModeIsOn = Standard_False;
208   myView->SetComputedMode (myHlrModeIsOn);
209   myView->Redraw();
210   QApplication::restoreOverrideCursor();
211 }
212
213 void View::hlrOn()
214 {
215   QApplication::setOverrideCursor( Qt::WaitCursor );
216   myHlrModeIsOn = Standard_True;
217   myView->SetComputedMode (myHlrModeIsOn);
218   myView->Redraw();
219   QApplication::restoreOverrideCursor();
220 }
221
222 void View::SetRaytracedShadows (bool theState)
223 {
224   myView->ChangeRenderingParams().IsShadowEnabled = theState;
225
226   myIsShadowsEnabled = theState;
227
228   myContext->UpdateCurrentViewer();
229 }
230
231 void View::SetRaytracedReflections (bool theState)
232 {
233   myView->ChangeRenderingParams().IsReflectionEnabled = theState;
234
235   myIsReflectionsEnabled = theState;
236
237   myContext->UpdateCurrentViewer();
238 }
239
240 void View::onRaytraceAction()
241 {
242   QAction* aSentBy = (QAction*)sender();
243   
244   if (aSentBy == myRaytraceActions->at (ToolRaytracingId))
245   {
246     bool aState = myRaytraceActions->at (ToolRaytracingId)->isChecked(); 
247
248     QApplication::setOverrideCursor (Qt::WaitCursor);
249     if (aState)
250       EnableRaytracing();
251     else
252       DisableRaytracing();
253     QApplication::restoreOverrideCursor();
254   }
255
256   if (aSentBy == myRaytraceActions->at (ToolShadowsId))
257   {
258     bool aState = myRaytraceActions->at (ToolShadowsId)->isChecked(); 
259     SetRaytracedShadows (aState);
260   }
261
262   if (aSentBy == myRaytraceActions->at (ToolReflectionsId))
263   {
264     bool aState = myRaytraceActions->at (ToolReflectionsId)->isChecked();
265     SetRaytracedReflections (aState);
266   }
267
268   if (aSentBy == myRaytraceActions->at (ToolAntialiasingId))
269   {
270     bool aState = myRaytraceActions->at (ToolAntialiasingId)->isChecked();
271     SetRaytracedAntialiasing (aState);
272   }
273 }
274
275 void View::SetRaytracedAntialiasing (bool theState)
276 {
277   myView->ChangeRenderingParams().IsAntialiasingEnabled = theState;
278
279   myIsAntialiasingEnabled = theState;
280
281   myContext->UpdateCurrentViewer();
282 }
283
284 void View::EnableRaytracing()
285 {
286   if (!myIsRaytracing)
287     myView->ChangeRenderingParams().Method = Graphic3d_RM_RAYTRACING;
288
289   myIsRaytracing = true;
290
291   myContext->UpdateCurrentViewer();
292 }
293
294 void View::DisableRaytracing()
295 {
296   if (myIsRaytracing)
297     myView->ChangeRenderingParams().Method = Graphic3d_RM_RASTERIZATION;
298
299   myIsRaytracing = false;
300
301   myContext->UpdateCurrentViewer();
302 }
303
304 void View::updateToggled( bool isOn )
305 {
306   QAction* sentBy = (QAction*)sender();
307
308   if( !isOn )
309     return;
310
311   for ( int i = ViewFitAllId; i < ViewHlrOffId; i++ )
312   {
313     QAction* anAction = myViewActions->at( i );
314     
315     if ( ( anAction == myViewActions->at( ViewFitAreaId ) ) ||
316          ( anAction == myViewActions->at( ViewZoomId ) ) ||
317          ( anAction == myViewActions->at( ViewPanId ) ) ||
318          ( anAction == myViewActions->at( ViewGlobalPanId ) ) ||
319          ( anAction == myViewActions->at( ViewRotationId ) ) )
320     {
321       if ( anAction && ( anAction != sentBy ) )
322       {
323         anAction->setCheckable( true );
324         anAction->setChecked( false );
325       }
326       else
327       {
328         if ( sentBy == myViewActions->at( ViewFitAreaId ) )
329           setCursor( *handCursor );
330         else if ( sentBy == myViewActions->at( ViewZoomId ) )
331           setCursor( *zoomCursor );
332         else if ( sentBy == myViewActions->at( ViewPanId ) )
333           setCursor( *panCursor );
334         else if ( sentBy == myViewActions->at( ViewGlobalPanId ) )
335           setCursor( *globPanCursor );
336         else if ( sentBy == myViewActions->at( ViewRotationId ) )
337           setCursor( *rotCursor );
338         else
339           setCursor( *defCursor );
340
341         sentBy->setCheckable( false );
342       }
343     }
344   }
345 }
346
347 void View::initCursors()
348 {
349   if ( !defCursor )
350     defCursor = new QCursor( Qt::ArrowCursor );
351   if ( !handCursor )
352     handCursor = new QCursor( Qt::PointingHandCursor );
353   if ( !panCursor )
354     panCursor = new QCursor( Qt::SizeAllCursor );
355   if ( !globPanCursor )
356     globPanCursor = new QCursor( Qt::CrossCursor );
357   if ( !zoomCursor )
358     zoomCursor = new QCursor( QPixmap( ApplicationCommonWindow::getResourceDir() + QString( "/" ) + QObject::tr( "ICON_CURSOR_ZOOM" ) ) );
359   if ( !rotCursor )
360     rotCursor = new QCursor( QPixmap( ApplicationCommonWindow::getResourceDir() + QString( "/" ) + QObject::tr( "ICON_CURSOR_ROTATE" ) ) );
361 }
362
363 QList<QAction*>* View::getViewActions()
364 {
365   initViewActions();
366   return myViewActions;
367 }
368
369 QList<QAction*>* View::getRaytraceActions()
370 {
371   initRaytraceActions();
372   return myRaytraceActions;
373 }
374
375 /*!
376   Get paint engine for the OpenGL viewer. [ virtual public ]
377 */
378 QPaintEngine* View::paintEngine() const
379 {
380   return 0;
381 }
382
383 void View::initViewActions()
384 {
385   if ( myViewActions )
386     return;
387
388   myViewActions = new QList<QAction*>();
389   QString dir = ApplicationCommonWindow::getResourceDir() + QString( "/" );
390   QAction* a;
391
392   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_FITALL") ), QObject::tr("MNU_FITALL"), this );
393   a->setToolTip( QObject::tr("TBR_FITALL") );
394   a->setStatusTip( QObject::tr("TBR_FITALL") );
395   connect( a, SIGNAL( triggered() ) , this, SLOT( fitAll() ) );
396   myViewActions->insert(ViewFitAllId, a);
397
398   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_FITAREA") ), QObject::tr("MNU_FITAREA"), this );
399   a->setToolTip( QObject::tr("TBR_FITAREA") );
400   a->setStatusTip( QObject::tr("TBR_FITAREA") );
401   connect( a, SIGNAL( triggered() ) , this, SLOT( fitArea() ) );
402
403   a->setCheckable( true );
404   connect( a, SIGNAL( toggled( bool ) ) , this, SLOT( updateToggled( bool ) ) );
405   myViewActions->insert( ViewFitAreaId, a );
406
407   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_ZOOM") ), QObject::tr("MNU_ZOOM"), this );
408   a->setToolTip( QObject::tr("TBR_ZOOM") );
409   a->setStatusTip( QObject::tr("TBR_ZOOM") );
410   connect( a, SIGNAL( triggered() ) , this, SLOT( zoom() ) );
411
412   a->setCheckable( true );
413   connect( a, SIGNAL( toggled(bool) ) , this, SLOT( updateToggled(bool) ) );
414   myViewActions->insert( ViewZoomId, a );
415
416   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_PAN") ), QObject::tr("MNU_PAN"), this );
417   a->setToolTip( QObject::tr("TBR_PAN") );
418   a->setStatusTip( QObject::tr("TBR_PAN") );
419   connect( a, SIGNAL( triggered() ) , this, SLOT( pan() ) );
420
421   a->setCheckable( true );
422   connect( a, SIGNAL( toggled(bool) ) , this, SLOT( updateToggled(bool) ) );
423   myViewActions->insert( ViewPanId, a );
424
425   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_GLOBALPAN") ), QObject::tr("MNU_GLOBALPAN"), this );
426   a->setToolTip( QObject::tr("TBR_GLOBALPAN") );
427   a->setStatusTip( QObject::tr("TBR_GLOBALPAN") );
428   connect( a, SIGNAL( triggered() ) , this, SLOT( globalPan() ) );
429
430   a->setCheckable( true );
431   connect( a, SIGNAL( toggled(bool) ) , this, SLOT( updateToggled(bool) ) );
432   myViewActions->insert( ViewGlobalPanId, a );
433
434   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_FRONT") ), QObject::tr("MNU_FRONT"), this );
435   a->setToolTip( QObject::tr("TBR_FRONT") );
436   a->setStatusTip( QObject::tr("TBR_FRONT") );
437   connect( a, SIGNAL( triggered() ) , this, SLOT( front() ) );
438   myViewActions->insert( ViewFrontId, a );
439
440   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_BACK") ), QObject::tr("MNU_BACK"), this );
441   a->setToolTip( QObject::tr("TBR_BACK") );
442   a->setStatusTip( QObject::tr("TBR_BACK") );
443   connect( a, SIGNAL( triggered() ) , this, SLOT( back() ) );
444   myViewActions->insert(ViewBackId, a);
445
446   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_TOP") ), QObject::tr("MNU_TOP"), this );
447   a->setToolTip( QObject::tr("TBR_TOP") );
448   a->setStatusTip( QObject::tr("TBR_TOP") );
449   connect( a, SIGNAL( triggered() ) , this, SLOT( top() ) );
450   myViewActions->insert( ViewTopId, a );
451
452   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_BOTTOM") ), QObject::tr("MNU_BOTTOM"), this );
453   a->setToolTip( QObject::tr("TBR_BOTTOM") );
454   a->setStatusTip( QObject::tr("TBR_BOTTOM") );
455   connect( a, SIGNAL( triggered() ) , this, SLOT( bottom() ) );
456   myViewActions->insert( ViewBottomId, a );
457
458   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_LEFT") ), QObject::tr("MNU_LEFT"), this );
459   a->setToolTip( QObject::tr("TBR_LEFT") );
460   a->setStatusTip( QObject::tr("TBR_LEFT") );
461   connect( a, SIGNAL( triggered() ) , this, SLOT( left() ) );
462   myViewActions->insert( ViewLeftId, a );
463
464   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_RIGHT") ), QObject::tr("MNU_RIGHT"), this );
465   a->setToolTip( QObject::tr("TBR_RIGHT") );
466   a->setStatusTip( QObject::tr("TBR_RIGHT") );
467   connect( a, SIGNAL( triggered() ) , this, SLOT( right() ) );
468   myViewActions->insert( ViewRightId, a );
469
470   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_AXO") ), QObject::tr("MNU_AXO"), this );
471   a->setToolTip( QObject::tr("TBR_AXO") );
472   a->setStatusTip( QObject::tr("TBR_AXO") );
473   connect( a, SIGNAL( triggered() ) , this, SLOT( axo() ) );
474   myViewActions->insert( ViewAxoId, a );
475
476   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_ROTATION") ), QObject::tr("MNU_ROTATION"), this );
477   a->setToolTip( QObject::tr("TBR_ROTATION") );
478   a->setStatusTip( QObject::tr("TBR_ROTATION") );
479   connect( a, SIGNAL( triggered() ) , this, SLOT( rotation() ) );
480   a->setCheckable( true );
481   connect( a, SIGNAL( toggled(bool) ) , this, SLOT( updateToggled(bool) ) );
482   myViewActions->insert( ViewRotationId, a );
483
484   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_RESET") ), QObject::tr("MNU_RESET"), this );
485   a->setToolTip( QObject::tr("TBR_RESET") );
486   a->setStatusTip( QObject::tr("TBR_RESET") );
487   connect( a, SIGNAL( triggered() ) , this, SLOT( reset() ) );
488   myViewActions->insert( ViewResetId, a );
489
490   QActionGroup* ag = new QActionGroup( this );
491
492   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_HLROFF") ), QObject::tr("MNU_HLROFF"), this );
493   a->setToolTip( QObject::tr("TBR_HLROFF") );
494   a->setStatusTip( QObject::tr("TBR_HLROFF") );
495   connect( a, SIGNAL( triggered() ) , this, SLOT( hlrOff() ) );
496   a->setCheckable( true );
497   ag->addAction(a);
498   myViewActions->insert(ViewHlrOffId, a);
499
500   a = new QAction( QPixmap( dir+QObject::tr("ICON_VIEW_HLRON") ), QObject::tr("MNU_HLRON"), this );
501   a->setToolTip( QObject::tr("TBR_HLRON") );
502   a->setStatusTip( QObject::tr("TBR_HLRON") );
503   connect( a, SIGNAL( triggered() ) ,this, SLOT( hlrOn() ) );
504   
505   a->setCheckable( true );
506   ag->addAction(a);
507   myViewActions->insert( ViewHlrOnId, a );
508 }
509
510 void View::initRaytraceActions()
511 {
512   if ( myRaytraceActions )
513     return;
514
515   myRaytraceActions = new QList<QAction*>();
516   QString dir = ApplicationCommonWindow::getResourceDir() + QString( "/" );
517   QAction* a;
518
519   a = new QAction( QPixmap( dir+QObject::tr("ICON_TOOL_RAYTRACING") ), QObject::tr("MNU_TOOL_RAYTRACING"), this );
520   a->setToolTip( QObject::tr("TBR_TOOL_RAYTRACING") );
521   a->setStatusTip( QObject::tr("TBR_TOOL_RAYTRACING") );
522   a->setCheckable( true );
523   a->setChecked( false );
524   connect( a, SIGNAL( triggered() ) , this, SLOT( onRaytraceAction() ) );
525   myRaytraceActions->insert( ToolRaytracingId, a );
526
527   a = new QAction( QPixmap( dir+QObject::tr("ICON_TOOL_SHADOWS") ), QObject::tr("MNU_TOOL_SHADOWS"), this );
528   a->setToolTip( QObject::tr("TBR_TOOL_SHADOWS") );
529   a->setStatusTip( QObject::tr("TBR_TOOL_SHADOWS") );
530   a->setCheckable( true );
531   a->setChecked( true );
532   connect( a, SIGNAL( triggered() ) , this, SLOT( onRaytraceAction() ) );
533   myRaytraceActions->insert( ToolShadowsId, a );
534
535   a = new QAction( QPixmap( dir+QObject::tr("ICON_TOOL_REFLECTIONS") ), QObject::tr("MNU_TOOL_REFLECTIONS"), this );
536   a->setToolTip( QObject::tr("TBR_TOOL_REFLECTIONS") );
537   a->setStatusTip( QObject::tr("TBR_TOOL_REFLECTIONS") );
538   a->setCheckable( true );
539   a->setChecked( false );
540   connect( a, SIGNAL( triggered() ) , this, SLOT( onRaytraceAction() ) );
541   myRaytraceActions->insert( ToolReflectionsId, a );
542
543   a = new QAction( QPixmap( dir+QObject::tr("ICON_TOOL_ANTIALIASING") ), QObject::tr("MNU_TOOL_ANTIALIASING"), this );
544   a->setToolTip( QObject::tr("TBR_TOOL_ANTIALIASING") );
545   a->setStatusTip( QObject::tr("TBR_TOOL_ANTIALIASING") );
546   a->setCheckable( true );
547   a->setChecked( false );
548   connect( a, SIGNAL( triggered() ) , this, SLOT( onRaytraceAction() ) );
549   myRaytraceActions->insert( ToolAntialiasingId, a );
550 }
551
552 void View::mousePressEvent( QMouseEvent* e )
553 {
554   if ( e->button() == Qt::LeftButton )
555     onLButtonDown( ( e->buttons() | e->modifiers() ), e->pos() );
556   else if ( e->button() == Qt::MidButton )
557     onMButtonDown( e->buttons() | e->modifiers(), e->pos() );
558   else if ( e->button() == Qt::RightButton )
559     onRButtonDown( e->buttons() | e->modifiers(), e->pos() );
560 }
561
562 void View::mouseReleaseEvent(QMouseEvent* e)
563 {
564   if ( e->button() == Qt::LeftButton )
565     onLButtonUp( e->buttons(), e->pos() );
566   else if ( e->button() == Qt::MidButton )
567     onMButtonUp( e->buttons(), e->pos() );
568   else if( e->button() == Qt::RightButton )
569     onRButtonUp( e->buttons(), e->pos() );
570 }
571
572 void View::mouseMoveEvent(QMouseEvent* e)
573 {
574   onMouseMove( e->buttons(), e->pos() );
575 }
576
577 void View::activateCursor( const CurrentAction3d mode )
578 {
579   switch( mode )
580   {
581     case CurAction3d_DynamicPanning:
582       setCursor( *panCursor );
583       break;
584     case CurAction3d_DynamicZooming:
585       setCursor( *zoomCursor );
586       break;
587     case CurAction3d_DynamicRotation:
588       setCursor( *rotCursor );
589       break;
590     case CurAction3d_GlobalPanning:
591       setCursor( *globPanCursor );
592       break;
593     case CurAction3d_WindowZooming:
594       setCursor( *handCursor );
595       break;
596     case CurAction3d_Nothing:
597     default:
598       setCursor( *defCursor );
599       break;
600   }
601 }
602
603 void View::onLButtonDown( const int/*Qt::MouseButtons*/ nFlags, const QPoint point )
604 {
605   //  save the current mouse coordinate in min
606   myXmin = point.x();
607   myYmin = point.y();
608   myXmax = point.x();
609   myYmax = point.y();
610
611   if ( nFlags & CASCADESHORTCUTKEY )
612   {
613     myCurrentMode = CurAction3d_DynamicZooming;
614   }
615   else
616   {
617     switch ( myCurrentMode )
618     {
619       case CurAction3d_Nothing:
620            if ( nFlags & MULTISELECTIONKEY )
621              MultiDragEvent( myXmax, myYmax, -1 );
622            else
623              DragEvent( myXmax, myYmax, -1 );
624            break;
625       case CurAction3d_DynamicZooming:
626            break;
627       case CurAction3d_WindowZooming:
628            break;
629       case CurAction3d_DynamicPanning:
630            break;
631       case CurAction3d_GlobalPanning:
632            break;
633       case CurAction3d_DynamicRotation:
634            if (myHlrModeIsOn)
635            {
636              myView->SetComputedMode (Standard_False);
637            }
638            myView->StartRotation( point.x(), point.y() );
639            break;
640       default:
641            throw Standard_Failure( "incompatible Current Mode" );
642            break;
643     }
644   }
645   activateCursor( myCurrentMode );
646 }
647
648 void View::onMButtonDown( const int/*Qt::MouseButtons*/ nFlags, const QPoint /*point*/ )
649 {
650   if ( nFlags & CASCADESHORTCUTKEY )
651     myCurrentMode = CurAction3d_DynamicPanning;
652   activateCursor( myCurrentMode );
653 }
654
655 void View::onRButtonDown( const int/*Qt::MouseButtons*/ nFlags, const QPoint point )
656 {
657   if ( nFlags & CASCADESHORTCUTKEY )
658   {
659     if (myHlrModeIsOn)
660     {
661       myView->SetComputedMode (Standard_False);
662     }
663     myCurrentMode = CurAction3d_DynamicRotation;
664     myView->StartRotation( point.x(), point.y() );
665   }
666   else
667   {
668     Popup( point.x(), point.y() );
669   }
670   activateCursor( myCurrentMode );
671 }
672
673 void View::onLButtonUp( Qt::MouseButtons nFlags, const QPoint point )
674 {
675     switch( myCurrentMode )
676     {
677         case CurAction3d_Nothing:
678             if ( point.x() == myXmin && point.y() == myYmin )
679             {
680               // no offset between down and up --> selectEvent
681               myXmax = point.x();
682               myYmax = point.y();
683               if ( nFlags & MULTISELECTIONKEY )
684                   MultiInputEvent( point.x(), point.y() );
685               else
686                   InputEvent( point.x(), point.y() );
687             }
688             else
689             {
690               DrawRectangle( myXmin, myYmin, myXmax, myYmax, Standard_False );
691               myXmax = point.x();
692               myYmax = point.y();
693               if ( nFlags & MULTISELECTIONKEY )
694                   MultiDragEvent( point.x(), point.y(), 1 );
695               else
696                   DragEvent( point.x(), point.y(), 1 );
697             }
698             break;
699         case CurAction3d_DynamicZooming:
700             myCurrentMode = CurAction3d_Nothing;
701             noActiveActions();
702             break;
703         case CurAction3d_WindowZooming:
704             DrawRectangle( myXmin, myYmin, myXmax, myYmax, Standard_False );//,LongDash);
705             myXmax = point.x();
706             myYmax = point.y();
707             if ( (abs( myXmin - myXmax ) > ValZWMin ) ||
708                  (abs( myYmin - myYmax ) > ValZWMin ) )
709               myView->WindowFitAll( myXmin, myYmin, myXmax, myYmax );
710             myCurrentMode = CurAction3d_Nothing;
711             noActiveActions();
712             break;
713         case CurAction3d_DynamicPanning:
714             myCurrentMode = CurAction3d_Nothing;
715             noActiveActions();
716             break;
717         case CurAction3d_GlobalPanning :
718             myView->Place( point.x(), point.y(), myCurZoom );
719             myCurrentMode = CurAction3d_Nothing;
720             noActiveActions();
721             break;
722         case CurAction3d_DynamicRotation:
723             myCurrentMode = CurAction3d_Nothing;
724             noActiveActions();
725             break;
726         default:
727             throw Standard_Failure(" incompatible Current Mode ");
728             break;
729     }
730     activateCursor( myCurrentMode );
731     ApplicationCommonWindow::getApplication()->onSelectionChanged();
732 }
733
734 void View::onMButtonUp( Qt::MouseButtons /*nFlags*/, const QPoint /*point*/ )
735 {
736     myCurrentMode = CurAction3d_Nothing;
737     activateCursor( myCurrentMode );
738 }
739
740 void View::onRButtonUp( Qt::MouseButtons /*nFlags*/, const QPoint point )
741 {
742     if ( myCurrentMode == CurAction3d_Nothing )
743         Popup( point.x(), point.y() );
744     else
745     {
746         QApplication::setOverrideCursor( Qt::WaitCursor );
747         // reset tyhe good Degenerated mode according to the strored one
748         //   --> dynamic rotation may have change it
749         if (myHlrModeIsOn)
750         {
751           myView->SetComputedMode (myHlrModeIsOn);
752           myView->Redraw();
753         }
754         QApplication::restoreOverrideCursor();
755         myCurrentMode = CurAction3d_Nothing;
756     }
757     activateCursor( myCurrentMode );
758 }
759
760 void View::onMouseMove( Qt::MouseButtons nFlags, const QPoint point )
761 {
762     if ( nFlags & Qt::LeftButton || nFlags & Qt::RightButton || nFlags & Qt::MidButton )
763     {
764     switch ( myCurrentMode )
765     {
766         case CurAction3d_Nothing:
767           myXmax = point.x();
768           myYmax = point.y();
769           DrawRectangle( myXmin, myYmin, myXmax, myYmax, Standard_False );
770           if ( nFlags & MULTISELECTIONKEY )
771               MultiDragEvent( myXmax, myYmax, 0 );
772           else
773             DragEvent( myXmax, myYmax, 0 );
774             DrawRectangle( myXmin, myYmin, myXmax, myYmax, Standard_True );
775             break;
776         case CurAction3d_DynamicZooming:
777           myView->Zoom( myXmax, myYmax, point.x(), point.y() );
778           myXmax = point.x();
779           myYmax = point.y();
780           break;
781         case CurAction3d_WindowZooming:
782           myXmax = point.x();
783           myYmax = point.y();
784           DrawRectangle( myXmin, myYmin, myXmax, myYmax, Standard_False );
785           DrawRectangle( myXmin, myYmin, myXmax, myYmax, Standard_True );
786           break;
787         case CurAction3d_DynamicPanning:
788           myView->Pan( point.x() - myXmax, myYmax - point.y() );
789           myXmax = point.x();
790           myYmax = point.y();
791           break;
792         case CurAction3d_GlobalPanning:
793           break;
794         case CurAction3d_DynamicRotation:
795           myView->Rotation( point.x(), point.y() );
796           myView->Redraw();
797           break;
798         default:
799           throw Standard_Failure( "incompatible Current Mode" );
800           break;
801     }
802     }
803     else
804     {
805         myXmax = point.x();
806         myYmax = point.y();
807       if ( nFlags & MULTISELECTIONKEY )
808           MultiMoveEvent( point.x(), point.y() );
809       else
810           MoveEvent( point.x(), point.y() );
811     }
812 }
813
814 void View::DragEvent( const int x, const int y, const int TheState )
815 {
816     // TheState == -1  button down
817     // TheState ==  0  move
818     // TheState ==  1  button up
819
820     static Standard_Integer theButtonDownX = 0;
821     static Standard_Integer theButtonDownY = 0;
822
823     if ( TheState == -1 )
824     {
825         theButtonDownX = x;
826         theButtonDownY = y;
827     }
828
829     if ( TheState == 1 )
830     {
831         myContext->Select( theButtonDownX, theButtonDownY, x, y, myView, Standard_True );
832         emit selectionChanged();
833     }
834 }
835
836 void View::InputEvent( const int /*x*/, const int /*y*/ )
837 {
838   myContext->Select (Standard_True);
839   emit selectionChanged();
840 }
841
842 void View::MoveEvent( const int x, const int y )
843 {
844   myContext->MoveTo( x, y, myView, Standard_True );
845 }
846
847 void View::MultiMoveEvent( const int x, const int y )
848 {
849   myContext->MoveTo( x, y, myView, Standard_True );
850 }
851
852 void View::MultiDragEvent( const int x, const int y, const int TheState )
853 {
854     static Standard_Integer theButtonDownX = 0;
855     static Standard_Integer theButtonDownY = 0;
856
857     if ( TheState == -1 )
858     {
859         theButtonDownX = x;
860         theButtonDownY = y;
861     }
862     if ( TheState == 0 )
863     {
864         myContext->ShiftSelect( theButtonDownX, theButtonDownY, x, y, myView, Standard_True );
865         emit selectionChanged();
866     }
867 }
868
869 void View::MultiInputEvent( const int /*x*/, const int /*y*/ )
870 {
871   myContext->ShiftSelect (Standard_True);
872   emit selectionChanged();
873 }
874
875 void View::Popup( const int /*x*/, const int /*y*/ )
876 {
877   ApplicationCommonWindow* stApp = ApplicationCommonWindow::getApplication();
878   QMdiArea* ws = ApplicationCommonWindow::getWorkspace();
879   QMdiSubWindow* w = ws->activeSubWindow();
880   if ( myContext->NbSelected() )
881   {
882     QList<QAction*>* aList = stApp->getToolActions();
883     QMenu* myToolMenu = new QMenu( 0 );
884     myToolMenu->addAction( aList->at( ApplicationCommonWindow::ToolWireframeId ) );
885     myToolMenu->addAction( aList->at( ApplicationCommonWindow::ToolShadingId ) );
886     myToolMenu->addAction( aList->at( ApplicationCommonWindow::ToolColorId ) );
887         
888     QMenu* myMaterMenu = new QMenu( myToolMenu );
889
890     QList<QAction*>* aMeterActions = ApplicationCommonWindow::getApplication()->getMaterialActions();
891         
892     QString dir = ApplicationCommonWindow::getResourceDir() + QString( "/" );
893     myMaterMenu = myToolMenu->addMenu( QPixmap( dir+QObject::tr("ICON_TOOL_MATER")), QObject::tr("MNU_MATER") );
894     for ( int i = 0; i < aMeterActions->size(); i++ )
895       myMaterMenu->addAction( aMeterActions->at( i ) );
896        
897     myToolMenu->addAction( aList->at( ApplicationCommonWindow::ToolTransparencyId ) );
898     myToolMenu->addAction( aList->at( ApplicationCommonWindow::ToolDeleteId ) );
899     addItemInPopup(myToolMenu);
900     myToolMenu->exec( QCursor::pos() );
901     delete myToolMenu;
902   }
903   else
904   {
905     if (!myBackMenu)
906     {
907       myBackMenu = new QMenu( 0 );
908
909       QAction* a = new QAction( QObject::tr("MNU_CH_BACK"), this );
910       a->setToolTip( QObject::tr("TBR_CH_BACK") );
911       connect( a, SIGNAL( triggered() ), this, SLOT( onBackground() ) );
912       myBackMenu->addAction( a );  
913       addItemInPopup(myBackMenu);
914
915       a = new QAction( QObject::tr("MNU_CH_ENV_MAP"), this );
916       a->setToolTip( QObject::tr("TBR_CH_ENV_MAP") );
917       connect( a, SIGNAL( triggered() ), this, SLOT( onEnvironmentMap() ) );
918       a->setCheckable( true );
919       a->setChecked( false );
920       myBackMenu->addAction( a );  
921       addItemInPopup(myBackMenu);
922     }
923
924     myBackMenu->exec( QCursor::pos() );
925   }
926   if ( w )
927     w->setFocus();
928 }
929
930 void View::addItemInPopup( QMenu* /*theMenu*/)
931 {
932 }
933
934 void View::DrawRectangle(const int MinX, const int MinY,
935        const int MaxX, const int MaxY, const bool Draw)
936
937   static Standard_Integer StoredMinX, StoredMaxX, StoredMinY, StoredMaxY;
938   static Standard_Boolean m_IsVisible;
939
940   StoredMinX = (MinX < MaxX) ? MinX: MaxX ;
941   StoredMinY = (MinY < MaxY) ? MinY: MaxY ;
942   StoredMaxX = (MinX > MaxX) ? MinX: MaxX ;
943   StoredMaxY = (MinY > MaxY) ? MinY: MaxY ;
944
945   QRect aRect;
946   aRect.setRect( StoredMinX, StoredMinY, abs(StoredMaxX-StoredMinX), abs(StoredMaxY-StoredMinY));
947
948   if ( !myRectBand ) 
949   {
950     myRectBand = new QRubberBand( QRubberBand::Rectangle, this );
951     myRectBand->setStyle( QStyleFactory::create("windows") );
952     myRectBand->setGeometry( aRect );
953     myRectBand->show();
954
955     /*QPalette palette;
956     palette.setColor(myRectBand->foregroundRole(), Qt::white);
957     myRectBand->setPalette(palette);*/
958   }
959
960   if ( m_IsVisible && !Draw ) // move or up  : erase at the old position
961   {
962     myRectBand->hide();
963     delete myRectBand;
964     myRectBand = 0;
965     m_IsVisible = false;
966   }
967
968   if (Draw) // move : draw
969   {
970     //aRect.setRect( StoredMinX, StoredMinY, abs(StoredMaxX-StoredMinX), abs(StoredMaxY-StoredMinY));
971     m_IsVisible = true;
972     myRectBand->setGeometry( aRect );
973     //myRectBand->show();
974   }
975 }
976
977 void View::noActiveActions()
978 {
979     for ( int i = ViewFitAllId; i < ViewHlrOffId ; i++ )
980     {
981         QAction* anAction = myViewActions->at( i );
982         if( ( anAction == myViewActions->at( ViewFitAreaId ) ) ||
983             ( anAction == myViewActions->at( ViewZoomId ) ) ||
984             ( anAction == myViewActions->at( ViewPanId ) ) ||
985             ( anAction == myViewActions->at( ViewGlobalPanId ) ) ||
986             ( anAction == myViewActions->at( ViewRotationId ) ) )
987         {
988             setCursor( *defCursor );
989             anAction->setCheckable( true );
990             anAction->setChecked( false );
991         }
992     }
993 }
994
995 void View::onBackground()
996 {
997     QColor aColor ;
998     Standard_Real R1;
999     Standard_Real G1;
1000     Standard_Real B1;
1001     myView->BackgroundColor(Quantity_TOC_RGB,R1,G1,B1);
1002     aColor.setRgb((Standard_Integer)(R1 * 255), (Standard_Integer)(G1 * 255), (Standard_Integer)(B1 * 255));
1003
1004     QColor aRetColor = QColorDialog::getColor(aColor);
1005
1006     if( aRetColor.isValid() )
1007     {
1008         R1 = aRetColor.red()/255.;
1009         G1 = aRetColor.green()/255.;
1010         B1 = aRetColor.blue()/255.;
1011         myView->SetBackgroundColor(Quantity_TOC_RGB,R1,G1,B1);
1012     }
1013     myView->Redraw();
1014 }
1015
1016 void View::onEnvironmentMap()
1017 {
1018   if (myBackMenu->actions().at(1)->isChecked())
1019   {
1020     QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "",
1021                            tr("All Image Files (*.bmp *.gif *.jpg *.jpeg *.png *.tga)"));
1022     
1023     const TCollection_AsciiString anUtf8Path (fileName.toUtf8().data());
1024     
1025     Handle(Graphic3d_TextureEnv) aTexture = new Graphic3d_TextureEnv( anUtf8Path );
1026
1027     myView->SetTextureEnv (aTexture);
1028   }
1029   else
1030   {
1031     myView->SetTextureEnv (Handle(Graphic3d_TextureEnv)());
1032   }
1033   
1034   myView->Redraw();
1035 }
1036
1037 bool View::dump(Standard_CString theFile)
1038 {
1039   return myView->Dump(theFile);
1040 }
1041
1042 Handle(V3d_View)& View::getView()
1043 {
1044   return myView;
1045 }
1046
1047 Handle(AIS_InteractiveContext)& View::getContext()
1048 {
1049   return myContext;
1050 }
1051
1052 View::CurrentAction3d View::getCurrentMode()
1053 {
1054   return myCurrentMode;
1055 }
1056
1057
1058