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