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 | |
47 | static QCursor* defCursor = NULL; |
48 | static QCursor* handCursor = NULL; |
49 | static QCursor* panCursor = NULL; |
50 | static QCursor* globPanCursor = NULL; |
51 | static QCursor* zoomCursor = NULL; |
52 | static QCursor* rotCursor = NULL; |
53 | |
54 | View::View( Handle(AIS_InteractiveContext) theContext, QWidget* parent ) |
55 | : QWidget( parent ), |
56 | myViewActions( 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 | |
160 | View::~View() |
161 | { |
162 | } |
163 | |
164 | void 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 | |
190 | void View::paintEvent( QPaintEvent * e ) |
191 | { |
192 | // QApplication::syncX(); |
193 | if( myFirst ) |
194 | { |
195 | init(); |
196 | myFirst = false; |
197 | } |
198 | myView->Redraw(); |
199 | } |
200 | |
201 | void View::resizeEvent( QResizeEvent * e) |
202 | { |
203 | // QApplication::syncX(); |
204 | if( !myView.IsNull() ) |
205 | { |
206 | myView->MustBeResized(); |
207 | } |
208 | } |
209 | |
210 | void View::fitAll() |
211 | { |
212 | myView->FitAll(); |
213 | myView->ZFitAll(); |
214 | myView->Redraw(); |
215 | } |
216 | |
217 | void View::fitArea() |
218 | { |
219 | myCurrentMode = CurAction3d_WindowZooming; |
220 | } |
221 | |
222 | void View::zoom() |
223 | { |
224 | myCurrentMode = CurAction3d_DynamicZooming; |
225 | } |
226 | |
227 | void View::pan() |
228 | { |
229 | myCurrentMode = CurAction3d_DynamicPanning; |
230 | } |
231 | |
232 | void View::rotation() |
233 | { |
234 | myCurrentMode = CurAction3d_DynamicRotation; |
235 | } |
236 | |
237 | void 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 | |
247 | void View::front() |
248 | { |
249 | myView->SetProj( V3d_Xpos ); |
250 | } |
251 | |
252 | void View::back() |
253 | { |
254 | myView->SetProj( V3d_Xneg ); |
255 | } |
256 | |
257 | void View::top() |
258 | { |
259 | myView->SetProj( V3d_Zpos ); |
260 | } |
261 | |
262 | void View::bottom() |
263 | { |
264 | myView->SetProj( V3d_Zneg ); |
265 | } |
266 | |
267 | void View::left() |
268 | { |
269 | myView->SetProj( V3d_Ypos ); |
270 | } |
271 | |
272 | void View::right() |
273 | { |
274 | myView->SetProj( V3d_Yneg ); |
275 | } |
276 | |
277 | void View::axo() |
278 | { |
279 | myView->SetProj( V3d_XposYnegZpos ); |
280 | } |
281 | |
282 | void View::reset() |
283 | { |
284 | myView->Reset(); |
285 | } |
286 | |
287 | void View::hlrOff() |
288 | { |
289 | QApplication::setOverrideCursor( Qt::WaitCursor ); |
290 | myView->SetDegenerateModeOn(); |
291 | myDegenerateModeIsOn = Standard_True; |
292 | QApplication::restoreOverrideCursor(); |
293 | } |
294 | |
295 | void View::hlrOn() |
296 | { |
297 | QApplication::setOverrideCursor( Qt::WaitCursor ); |
298 | myView->SetDegenerateModeOff(); |
299 | myDegenerateModeIsOn = Standard_False; |
300 | QApplication::restoreOverrideCursor(); |
301 | } |
302 | |
303 | void 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 | |
345 | void 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 | |
361 | QList<QAction*>* View::getViewActions() |
362 | { |
363 | initViewActions(); |
364 | return myViewActions; |
365 | } |
366 | |
4d183a4b |
367 | /*! |
368 | Get paint engine for the OpenGL viewer. [ virtual public ] |
369 | */ |
370 | QPaintEngine* View::paintEngine() const |
371 | { |
372 | return 0; |
373 | } |
374 | |
7fd59977 |
375 | void 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 | |
502 | void 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 | |
512 | void 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 | |
522 | void View::mouseMoveEvent(QMouseEvent* e) |
523 | { |
524 | onMouseMove( e->buttons(), e->pos() ); |
525 | } |
526 | |
527 | void 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 | |
553 | void 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 | |
596 | void View::onMButtonDown( const int/*Qt::MouseButtons*/ nFlags, const QPoint point ) |
597 | { |
598 | if ( nFlags & CASCADESHORTCUTKEY ) |
599 | myCurrentMode = CurAction3d_DynamicPanning; |
600 | activateCursor( myCurrentMode ); |
601 | } |
602 | |
603 | void 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 | |
619 | void 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 | |
680 | void View::onMButtonUp( Qt::MouseButtons nFlags, const QPoint point ) |
681 | { |
682 | myCurrentMode = CurAction3d_Nothing; |
683 | activateCursor( myCurrentMode ); |
684 | } |
685 | |
686 | void 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 | |
711 | void 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 | |
765 | void 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 | |
787 | void View::InputEvent( const int x, const int y ) |
788 | { |
789 | myContext->Select(); |
790 | emit selectionChanged(); |
791 | } |
792 | |
793 | void View::MoveEvent( const int x, const int y ) |
794 | { |
795 | myContext->MoveTo( x, y, myView ); |
796 | } |
797 | |
798 | void View::MultiMoveEvent( const int x, const int y ) |
799 | { |
800 | myContext->MoveTo( x, y, myView ); |
801 | } |
802 | |
803 | void 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 | |
820 | void View::MultiInputEvent( const int x, const int y ) |
821 | { |
822 | myContext->ShiftSelect(); |
823 | emit selectionChanged(); |
824 | } |
825 | |
826 | void 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 | |
869 | void View::addItemInPopup( QMenu* theMenu) |
870 | { |
871 | } |
872 | |
873 | void 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 | |
916 | void 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 | |
934 | void 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 | |
955 | bool 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 | |
987 | Handle(V3d_View)& View::getView() |
988 | { |
989 | return myView; |
990 | } |
991 | |
992 | Handle(AIS_InteractiveContext)& View::getContext() |
993 | { |
994 | return myContext; |
995 | } |
996 | |
997 | View::CurrentAction3d View::getCurrentMode() |
998 | { |
999 | return myCurrentMode; |
1000 | } |
1001 | |
1002 | |
1003 | |