Salome HOME
Update from BR_V5_DEV 13Feb2009
[modules/gui.git] / src / GLViewer / GLViewer_ViewFrame.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  Author : OPEN CASCADE
23 // File:      GLViewer_ViewFrame.cxx
24 // Created:   November, 2004
25 //#include <GLViewerAfx.h>
26 //
27 #include "GLViewer_ViewFrame.h"
28 #include "GLViewer_Viewer.h"
29 #include "GLViewer_ViewPort2d.h"
30
31 #include <QtxToolBar.h>
32 #include <QtxMultiAction.h>
33 #include <QtxActionToolMgr.h>
34
35 #include <SUIT_Desktop.h>
36 #include <SUIT_Session.h>
37 #include <SUIT_ResourceMgr.h>
38 #include <SUIT_MessageBox.h>
39
40 #include <QColor>
41 #include <QFileDialog>
42 #include <QImage>
43 #include <QHBoxLayout>
44 #include <QString>
45 #include <QFrame>
46 #include <QMouseEvent>
47 #include <QKeyEvent>
48 #include <QWheelEvent>
49
50 #ifdef WIN32
51 #include <Standard_Integer.hxx>
52 #include <iostream>
53 using namespace std;
54 #endif
55
56 /*!
57     Constructor
58 */
59 GLViewer_ViewFrame::GLViewer_ViewFrame( SUIT_Desktop* d, GLViewer_Viewer* vw )
60 : SUIT_ViewWindow( d ),
61 myViewer( vw ),
62 myVP( 0 )
63 {
64     QFrame* client = new QFrame( this );
65     setCentralWidget( client );
66
67     QBoxLayout* layout = new QHBoxLayout( client );
68     layout->setMargin( 0 );
69     layout->setSpacing( 0 );
70
71     GLViewer_ViewPort2d* vp = new GLViewer_ViewPort2d( client, this );
72     setViewPort( vp );
73     setBackgroundColor( Qt::white );
74     layout->addWidget( vp );
75
76     createActions();
77     createToolBar();
78 }
79
80 /*!
81     Destructor
82 */
83 GLViewer_ViewFrame::~GLViewer_ViewFrame()
84 {
85 }
86
87 /*!
88   Creates actions of GL view frame
89 */
90 void GLViewer_ViewFrame::createActions()
91 {
92   SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
93   QtxAction* aAction;
94
95   // Dump view
96   aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_DUMP" ) ),
97                           tr( "MNU_DUMP_VIEW" ), 0, this);
98   aAction->setStatusTip(tr("DSC_DUMP_VIEW"));
99   connect(aAction, SIGNAL(activated()), this, SLOT(onDumpView()));
100   toolMgr()->registerAction( aAction, DumpId );
101
102   // FitAll
103   aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITALL" ) ),
104                           tr( "MNU_FITALL" ), 0, this);
105   aAction->setStatusTip(tr("DSC_FITALL"));
106   connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitAll()));
107   toolMgr()->registerAction( aAction, FitAllId );
108
109   // FitRect
110   aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITAREA" ) ),
111                           tr( "MNU_FITRECT" ), 0, this);
112   aAction->setStatusTip(tr("DSC_FITRECT"));
113   connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitArea()));
114   toolMgr()->registerAction( aAction, FitRectId );
115
116   // FitSelect
117   aAction = new QtxAction(tr("MNU_FITSELECT"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITSELECT" ) ),
118                           tr( "MNU_FITSELECT" ), 0, this);
119   aAction->setStatusTip(tr("DSC_FITSELECT"));
120   connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitSelect()));
121   toolMgr()->registerAction( aAction, FitSelectId );
122
123   // Zoom
124   aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_ZOOM" ) ),
125                           tr( "MNU_ZOOM_VIEW" ), 0, this);
126   aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
127   connect(aAction, SIGNAL(activated()), this, SLOT(onViewZoom()));
128   toolMgr()->registerAction( aAction, ZoomId );
129
130   // Panning
131   aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_PAN" ) ),
132                           tr( "MNU_PAN_VIEW" ), 0, this);
133   aAction->setStatusTip(tr("DSC_PAN_VIEW"));
134   connect(aAction, SIGNAL(activated()), this, SLOT(onViewPan()));
135   toolMgr()->registerAction( aAction, PanId );
136
137   // Global Panning
138   aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_GLOBALPAN" ) ),
139                           tr( "MNU_GLOBALPAN_VIEW" ), 0, this);
140   aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
141   connect(aAction, SIGNAL(activated()), this, SLOT(onViewGlobalPan()));
142   toolMgr()->registerAction( aAction, GlobalPanId );
143
144   aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_RESET" ) ),
145                           tr( "MNU_RESET_VIEW" ), 0, this);
146   aAction->setStatusTip(tr("DSC_RESET_VIEW"));
147   connect(aAction, SIGNAL(activated()), this, SLOT(onViewReset()));
148   toolMgr()->registerAction( aAction, ResetId );
149 }
150
151 /*!
152   Creates toolbar of GL view frame
153 */
154 void GLViewer_ViewFrame::createToolBar()
155 {
156   int tid = toolMgr()->createToolBar( tr("LBL_TOOLBAR_LABEL") );
157   toolMgr()->append( DumpId, tid );
158
159   QtxMultiAction* aScaleAction = new QtxMultiAction( this );
160   aScaleAction->insertAction( toolMgr()->action( FitAllId ) );
161   aScaleAction->insertAction( toolMgr()->action( FitRectId ) );
162   aScaleAction->insertAction( toolMgr()->action( FitSelectId ) );
163   aScaleAction->insertAction( toolMgr()->action( ZoomId ) );
164   toolMgr()->append( aScaleAction, tid );
165
166   QtxMultiAction* aPanAction = new QtxMultiAction( this );
167   aPanAction->insertAction( toolMgr()->action( PanId ) );
168   aPanAction->insertAction( toolMgr()->action( GlobalPanId ) );
169   toolMgr()->append( aPanAction, tid );
170
171   toolMgr()->append( toolMgr()->action( ResetId ), tid );
172 }
173
174 /*!
175     Sets the viewport for this frame
176 */
177 void GLViewer_ViewFrame::setViewPort( GLViewer_ViewPort* vp )
178 {
179     if ( myVP == vp )
180         return;
181
182     if ( myVP )
183     {
184         disconnect( myVP, SIGNAL( vpDrawExternal( QPainter* ) ), this, SIGNAL( vfDrawExternal( QPainter* ) ) );
185         disconnect( myVP, SIGNAL( vpMouseEvent( QMouseEvent* ) ), this, SLOT( mouseEvent( QMouseEvent* ) ) );
186         disconnect( myVP, SIGNAL( vpKeyEvent( QKeyEvent* ) ), this, SLOT( keyEvent( QKeyEvent* ) ) );
187         disconnect( myVP, SIGNAL( vpWheelEvent( QWheelEvent* ) ), this, SLOT( wheelEvent( QWheelEvent* ) ) );
188         disconnect( myVP, SIGNAL( contextMenuRequested( QContextMenuEvent* ) ),
189                     this, SIGNAL( contextMenuRequested( QContextMenuEvent* ) ) );
190     }
191     myVP = vp;
192     if ( myVP )
193     {
194         connect( myVP, SIGNAL( vpDrawExternal( QPainter* ) ), this, SIGNAL( vfDrawExternal( QPainter* ) ) );
195         connect( myVP, SIGNAL( vpMouseEvent( QMouseEvent* ) ), this, SLOT( mouseEvent( QMouseEvent* ) ) );
196         connect( myVP, SIGNAL( vpKeyEvent( QKeyEvent* ) ), this, SLOT( keyEvent( QKeyEvent* ) ) );
197         connect( myVP, SIGNAL( vpWheelEvent( QWheelEvent* ) ), this, SLOT( wheelEvent( QWheelEvent* ) ) );
198         connect( myVP, SIGNAL( contextMenuRequested( QContextMenuEvent* ) ),
199                  this, SIGNAL( contextMenuRequested( QContextMenuEvent* ) ) );
200     }
201 }
202
203 /*!
204     Returns the viewport of this frame. [ public ]
205 */
206 GLViewer_ViewPort* GLViewer_ViewFrame::getViewPort() const
207 {
208     return myVP;
209 }
210
211 /*!
212     Set background of the viewport. [ public ]
213 */
214 void GLViewer_ViewFrame::setBackgroundColor( const QColor& color )
215 {
216     if ( myVP )
217         myVP->setBackgroundColor( color );
218 }
219
220 /*!
221     Returns background of the viewport. [ public ]
222 */
223 QColor GLViewer_ViewFrame::backgroundColor() const
224 {
225     if ( myVP )
226         return myVP->backgroundColor();
227     return palette().color( backgroundRole() );
228 }
229
230 /*!
231     Sets the viewer for this view. [ public ]
232 */
233 void GLViewer_ViewFrame::setViewer( GLViewer_Viewer* v )
234 {
235     myViewer = v;
236 }
237
238 /*!
239     Returns the viewer of this view. [ public ]
240 */
241 GLViewer_Viewer* GLViewer_ViewFrame::getViewer() const
242 {
243     return myViewer;
244 }
245
246 /*!
247     Returns the preferred view size. [ virtual public ]
248 */
249 QSize GLViewer_ViewFrame::sizeHint() const
250 {
251     QWidget* p = parentWidget();
252     if ( p && p->inherits( "QWorkspaceChild" ) )
253         p = p->parentWidget();
254     if ( !p )
255         return QMainWindow::sizeHint();
256     return QSize( 9 * p->width() / 10 , 9 * p->height() / 10  );
257 }
258
259 /*!
260    Called by viewer's 'update()' method. Does nothing by default [ virtual public ]
261 */
262 void GLViewer_ViewFrame::onUpdate( int )
263 {
264 }
265
266 //#include <windows.h>
267
268 /*!
269   SLOT: called on dump view operation is activated, stores scene to raster file
270 */
271
272 QImage GLViewer_ViewFrame::dumpView()
273 {
274   QImage img;
275
276   GLViewer_Widget* aWidget = ((GLViewer_ViewPort2d*)myVP)->getGLWidget();
277   if ( aWidget )
278     img = aWidget->grabFrameBuffer();
279
280   return img;
281 }
282
283 /*!
284   Start panning
285 */
286 void GLViewer_ViewFrame::onViewPan()
287 {
288     myViewer->activateTransform( GLViewer_Viewer::Pan );
289 }
290
291 /*!
292   Start zooming
293 */
294 void GLViewer_ViewFrame::onViewZoom()
295 {
296     myViewer->activateTransform( GLViewer_Viewer::Zoom );
297 }
298
299 /*!
300   Start fit all
301 */
302 void GLViewer_ViewFrame::onViewFitAll()
303 {
304     myViewer->activateTransform( GLViewer_Viewer::FitAll );
305 }
306
307 /*!
308   Start fit area
309 */
310 void GLViewer_ViewFrame::onViewFitArea()
311 {
312     myViewer->activateTransform( GLViewer_Viewer::FitRect );
313 }
314
315 /*!
316   Start fit selected
317 */
318 void GLViewer_ViewFrame::onViewFitSelect()
319 {
320     myViewer->activateTransform( GLViewer_Viewer::FitSelect );
321 }
322
323 /*!
324   Start global panning
325 */
326 void GLViewer_ViewFrame::onViewGlobalPan()
327 {
328     myViewer->activateTransform( GLViewer_Viewer::PanGlobal );
329 }
330
331 /*!
332   Start rotating
333 */
334 void GLViewer_ViewFrame::onViewRotate()
335 {
336     //myViewer->activateTransform( GLViewer_Viewer::Rotate );
337 }
338
339 /*!
340   Start reset default view aspects
341 */
342 void GLViewer_ViewFrame::onViewReset()
343 {
344     myViewer->activateTransform( GLViewer_Viewer::Reset );
345 }
346
347 /*!
348   Dispatches mouse events
349 */
350 void GLViewer_ViewFrame::mouseEvent( QMouseEvent* e )
351 {
352   switch ( e->type() )
353   {
354   case QEvent::MouseButtonPress:
355     emit mousePressed( this, e );
356     break;
357   case QEvent::MouseButtonRelease:
358     emit mouseReleased( this, e );
359     break;
360   case QEvent::MouseButtonDblClick:
361     emit mouseDoubleClicked( this, e );
362     break;
363   case QEvent::MouseMove:
364     emit mouseMoving( this, e );
365     break;
366   default:
367     break;
368   }
369 }
370
371 /*!
372   Dispatches key events
373 */
374 void GLViewer_ViewFrame::keyEvent( QKeyEvent* e )
375 {
376   switch ( e->type() )
377   {
378   case QEvent::KeyPress:
379     emit keyPressed( this, e );
380     break;
381   case QEvent::KeyRelease:
382     emit keyReleased( this, e );
383     break;
384   default:
385     break;
386   }
387 }
388
389 /*!
390   Dispatches wheel events
391 */
392 void GLViewer_ViewFrame::wheelEvent( QWheelEvent* e )
393 {
394   switch ( e->type() )
395   {
396   case QEvent::Wheel:
397     emit wheeling( this, e );
398     break;
399   default:
400     break;
401   }
402 }
403
404 /*!
405   \return the visual parameters of this view as a formated string
406 */
407 QString GLViewer_ViewFrame::getVisualParameters()
408 {
409   QString retStr;
410   if ( myVP && myVP->inherits( "GLViewer_ViewPort2d" ) ) {
411     GLViewer_ViewPort2d* vp2d = (GLViewer_ViewPort2d*)myVP;
412     GLfloat xSc, ySc, xPan, yPan;
413     vp2d->getScale( xSc, ySc );
414     vp2d->getPan( xPan, yPan );
415     retStr.sprintf( "%.12e*%.12e*%.12e*%.12e", xSc, ySc, xPan, yPan );
416   }
417   return retStr;
418 }
419
420 /*!
421   The method restores visual parameters of this view from a formated string
422 */
423 void GLViewer_ViewFrame::setVisualParameters( const QString& parameters )
424 {
425   QStringList paramsLst = parameters.split( '*' );
426   if ( myVP && myVP->inherits( "GLViewer_ViewPort2d" ) && paramsLst.size() == 4) {
427     GLViewer_ViewPort2d* vp2d = (GLViewer_ViewPort2d*)myVP;
428
429     GLfloat xSc, ySc, xPan, yPan;
430     xSc = paramsLst[0].toDouble();
431     ySc = paramsLst[1].toDouble();
432     xPan = paramsLst[2].toDouble();
433     yPan = paramsLst[3].toDouble();
434
435     vp2d->getGLWidget()->setScale( xSc, ySc, 1. );
436     vp2d->getGLWidget()->setPan( xPan, yPan, 0. );
437   }
438 }