1 // File: GLViewer_ViewFrame.cxx
2 // Created: November, 2004
4 // Copyright (C) CEA 2004
6 /***************************************************************************
7 ** Class: GLViewer_ViewFrame
8 ** Descr: Frame window for viewport in QAD-based application
10 ** Created: UI team, 05.09.00
11 ****************************************************************************/
13 #include "GLViewer_ViewFrame.h"
15 #include "GLViewer_Viewer.h"
16 #include "GLViewer_Viewer2d.h"
17 #include "GLViewer_ViewPort2d.h"
19 #include <SUIT_Desktop.h>
20 #include <SUIT_Session.h>
21 #include <SUIT_ToolButton.h>
22 #include <SUIT_ResourceMgr.h>
23 #include <QtxAction.h>
24 #include <SUIT_MessageBox.h>
27 #include <qfiledialog.h>
35 GLViewer_ViewFrame::GLViewer_ViewFrame( SUIT_Desktop* d, GLViewer_Viewer* vw )
36 : SUIT_ViewWindow( d ),
40 QFrame* client = new QFrame( this );
41 setCentralWidget( client );
43 QBoxLayout* layout = new QHBoxLayout( client, 1, 1 );
44 layout->setAutoAdd( true );
46 GLViewer_ViewPort2d* vp = new GLViewer_ViewPort2d( client, this );
47 //vp->turnGrid( true );
48 //vp->turnCompass( true );
49 //vp->enablePopup( false );
51 setBackgroundColor( Qt::white );
53 myToolBar = new QToolBar(this);
54 myToolBar->setCloseMode(QDockWindow::Undocked);
55 myToolBar->setLabel(tr("LBL_TOOLBAR_LABEL"));
63 GLViewer_ViewFrame::~GLViewer_ViewFrame()
67 //================================================================
68 // Function : createActions
70 //================================================================
71 void GLViewer_ViewFrame::createActions()
73 if ( !myActionsMap.isEmpty() )
77 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
80 aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_DUMP" ) ),
81 tr( "MNU_DUMP_VIEW" ), 0, this);
82 aAction->setStatusTip(tr("DSC_DUMP_VIEW"));
83 connect(aAction, SIGNAL(activated()), this, SLOT(onViewDump()));
84 myActionsMap[ DumpId ] = aAction;
87 aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITALL" ) ),
88 tr( "MNU_FITALL" ), 0, this);
89 aAction->setStatusTip(tr("DSC_FITALL"));
90 connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitAll()));
91 myActionsMap[ FitAllId ] = aAction;
94 aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITAREA" ) ),
95 tr( "MNU_FITRECT" ), 0, this);
96 aAction->setStatusTip(tr("DSC_FITRECT"));
97 connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitArea()));
98 myActionsMap[ FitRectId ] = aAction;
101 aAction = new QtxAction(tr("MNU_FITSELECT"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITSELECT" ) ),
102 tr( "MNU_FITSELECT" ), 0, this);
103 aAction->setStatusTip(tr("DSC_FITSELECT"));
104 connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitSelect()));
105 myActionsMap[ FitSelectId ] = aAction;
108 aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_ZOOM" ) ),
109 tr( "MNU_ZOOM_VIEW" ), 0, this);
110 aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
111 connect(aAction, SIGNAL(activated()), this, SLOT(onViewZoom()));
112 myActionsMap[ ZoomId ] = aAction;
115 aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_PAN" ) ),
116 tr( "MNU_PAN_VIEW" ), 0, this);
117 aAction->setStatusTip(tr("DSC_PAN_VIEW"));
118 connect(aAction, SIGNAL(activated()), this, SLOT(onViewPan()));
119 myActionsMap[ PanId ] = aAction;
122 aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_GLOBALPAN" ) ),
123 tr( "MNU_GLOBALPAN_VIEW" ), 0, this);
124 aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
125 connect(aAction, SIGNAL(activated()), this, SLOT(onViewGlobalPan()));
126 myActionsMap[ GlobalPanId ] = aAction;
128 aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_RESET" ) ),
129 tr( "MNU_RESET_VIEW" ), 0, this);
130 aAction->setStatusTip(tr("DSC_RESET_VIEW"));
131 connect(aAction, SIGNAL(activated()), this, SLOT(onViewReset()));
132 myActionsMap[ ResetId ] = aAction;
135 //================================================================
136 // Function : createToolBar
138 //================================================================
139 void GLViewer_ViewFrame::createToolBar()
141 myActionsMap[DumpId]->addTo(myToolBar);
143 SUIT_ToolButton* aScaleBtn = new SUIT_ToolButton(myToolBar);
144 aScaleBtn->AddAction(myActionsMap[FitAllId]);
145 aScaleBtn->AddAction(myActionsMap[FitRectId]);
146 aScaleBtn->AddAction(myActionsMap[FitSelectId]);
147 aScaleBtn->AddAction(myActionsMap[ZoomId]);
149 SUIT_ToolButton* aPanBtn = new SUIT_ToolButton(myToolBar);
150 aPanBtn->AddAction(myActionsMap[PanId]);
151 aPanBtn->AddAction(myActionsMap[GlobalPanId]);
153 myActionsMap[ResetId]->addTo(myToolBar);
157 Sets the viewport for this frame
159 void GLViewer_ViewFrame::setViewPort( GLViewer_ViewPort* vp )
166 disconnect( myVP, SIGNAL( vpDrawExternal( QPainter* ) ), this, SIGNAL( vfDrawExternal( QPainter* ) ) );
167 disconnect( myVP, SIGNAL( vpMouseEvent( QMouseEvent* ) ), this, SLOT( mouseEvent( QMouseEvent* ) ) );
168 disconnect( myVP, SIGNAL( vpKeyEvent( QKeyEvent* ) ), this, SLOT( keyEvent( QKeyEvent* ) ) );
169 disconnect( myVP, SIGNAL(contextMenuRequested( QContextMenuEvent * )),
170 this, SIGNAL(contextMenuRequested( QContextMenuEvent * )) );
171 disconnect( myVP, SIGNAL( vpWheelEvent( QWheelEvent* ) ), this, SLOT( wheelEvent( QWheelEvent* ) ) );
176 connect( myVP, SIGNAL( vpDrawExternal( QPainter* ) ), this, SIGNAL( vfDrawExternal( QPainter* ) ) );
177 connect( myVP, SIGNAL( vpMouseEvent( QMouseEvent* ) ), this, SLOT( mouseEvent( QMouseEvent* ) ) );
178 connect( myVP, SIGNAL( vpKeyEvent( QKeyEvent* ) ), this, SLOT( keyEvent( QKeyEvent* ) ) );
179 connect( myVP, SIGNAL(contextMenuRequested( QContextMenuEvent * )),
180 this, SIGNAL(contextMenuRequested( QContextMenuEvent * )) );
181 connect( myVP, SIGNAL( vpWheelEvent( QWheelEvent* ) ), this, SLOT( wheelEvent( QWheelEvent* ) ) );
186 Returns the viewport of this frame. [ public ]
188 GLViewer_ViewPort* GLViewer_ViewFrame::getViewPort() const
194 Set background of the viewport. [ public ]
196 void GLViewer_ViewFrame::setBackgroundColor( const QColor& color )
199 myVP->setBackgroundColor( color );
203 Returns background of the viewport. [ public ]
205 QColor GLViewer_ViewFrame::backgroundColor() const
208 return myVP->backgroundColor();
209 return QMainWindow::backgroundColor();
213 Sets the viewer for this view. [ public ]
215 void GLViewer_ViewFrame::setViewer( GLViewer_Viewer* v )
221 Returns the viewer of this view. [ public ]
223 GLViewer_Viewer* GLViewer_ViewFrame::getViewer() const
229 Returns the preferred view size. [ virtual public ]
231 QSize GLViewer_ViewFrame::sizeHint() const
233 QWidget* p = parentWidget();
234 if ( p && p->inherits( "QWorkspaceChild" ) )
235 p = p->parentWidget(); /* QWorkspaceChild: internal impl class in QWorkspace */
237 return QMainWindow::sizeHint();
238 return QSize( 9 * p->width() / 10 , 9 * p->height() / 10 );
242 Called by viewer's 'update()' method. Does nothing by default [ virtual public ]
244 void GLViewer_ViewFrame::onUpdate( int )
248 void GLViewer_ViewFrame::onViewDump()
250 GLViewer_Widget* aWidget = ((GLViewer_ViewPort2d*)myVP)->getGLWidget();
252 width = aWidget->width();
253 height = aWidget->height();
255 int imageSize = width*height*3;
256 unsigned char* imageBits = NULL;
258 int reserve_bytes = width % 4; //32 bits platform
259 imageSize = (width+reserve_bytes)*height*3;
260 imageBits = new unsigned char[imageSize];
268 HGLRC hglrc_old, hglrc;
272 hglrc_old = wglGetCurrentContext();
273 hdc_old = wglGetCurrentDC();
275 hdc = CreateCompatibleDC( hdc_old );
278 cout << "Can't create compatible DC. Last Error Code: " << GetLastError() << endl;
282 int sizeBmi = Standard_Integer( sizeof(BITMAPINFO) + sizeof(RGBQUAD)*3 );
283 PBITMAPINFO pBmi = (PBITMAPINFO)( new char[sizeBmi] );
284 ZeroMemory( pBmi, sizeBmi );
286 pBmi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); //sizeBmi
287 pBmi->bmiHeader.biWidth = width;
288 pBmi->bmiHeader.biHeight = height;
289 pBmi->bmiHeader.biPlanes = 1;
290 pBmi->bmiHeader.biBitCount = 24;
291 pBmi->bmiHeader.biCompression = BI_RGB;
294 hBmp = CreateDIBSection ( hdc, pBmi, DIB_RGB_COLORS, &ppvBits, NULL, 0 );
295 SelectObject ( hdc, hBmp );
298 PIXELFORMATDESCRIPTOR pfd;
299 ZeroMemory( &pfd, sizeof( PIXELFORMATDESCRIPTOR ) );
300 pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR );
302 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP;
303 pfd.iPixelType = PFD_TYPE_RGBA;
306 pfd.iLayerType = PFD_MAIN_PLANE;
308 int iPf = ChoosePixelFormat( hdc, &pfd);
311 if ( !DescribePixelFormat ( hdc, iPf, sizeof(PIXELFORMATDESCRIPTOR), &pfd ) )
313 cout << "Can't describe Pixel Format. Last Error Code: " << GetLastError() << endl;
316 if ( !SetPixelFormat(hdc, iPf, &pfd) )
318 cout << "Can't set Pixel Format. Last Error Code: " << GetLastError() << endl;
321 hglrc = wglCreateContext( hdc );
324 cout << "Can't create new GL Context. Last Error Code: " << GetLastError() << endl;
327 if( !wglMakeCurrent( hdc, hglrc) )
329 cout << "Can't make current new context!" << endl;
333 glViewport( 0, 0, width, height );
335 glMatrixMode( GL_PROJECTION );
337 GLfloat w_c = width / 2., h_c = height / 2.;
339 gluOrtho2D( -w_c, w_c, -h_c, h_c );
341 glMatrixMode( GL_MODELVIEW );
345 QColor aColor = ((GLViewer_ViewPort2d*)myVP)->backgroundColor();
346 glClearColor( ( GLfloat )aColor.red() / 255,
347 ( GLfloat )aColor.green() / 255,
348 ( GLfloat )aColor.blue() / 255,
351 aWidget->exportRepaint();
353 memset(&bi, 0, sizeof(BITMAPINFOHEADER));
354 bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
355 bi.bmiHeader.biPlanes = 1;
356 bi.bmiHeader.biBitCount = 24;
357 bi.bmiHeader.biHeight = -height;
358 bi.bmiHeader.biWidth = width;
359 bi.bmiHeader.biCompression = BI_RGB;
361 num = GetDIBits(hdc, hBmp, 0, height, imageBits, &bi, DIB_RGB_COLORS);
363 wglMakeCurrent( hdc_old, hglrc_old );
364 wglDeleteContext( hglrc );
370 unsigned int* aPix = NULL;
371 QImage anImage( width, height, 32 );
372 for( int i = 0; i < height; i++ )
374 memset( anImage.scanLine( i ), 0, sizeof(unsigned int)*width );
376 for( int j = 0; j < width; j++ )
378 pos = imageBits + i*width*3 + j*3 + reserve_bytes*i;
379 aPix = (unsigned int*)anImage.scanLine(i)+j;
380 *aPix = qRgb( *pos, *(pos+1), *(pos+2) );
386 QString aFilter( "*.bmp\n*.png" );
388 QFileDialog aFileDlg( QDir::current().absPath(), aFilter, this );
389 aFileDlg.setCaption( tr( "DUMP_VIEW_SAVE_FILE_DLG_CAPTION" ) );
390 aFileDlg.setMode( QFileDialog::AnyFile );
392 if( !aFileDlg.exec() )
395 QString aFileName = aFileDlg.selectedFile();
396 QString aFileExt = aFileDlg.selectedFilter();
398 if( aFileName.isEmpty() )
400 SUIT_MessageBox::error1( this,
401 tr( "DUMP_VIEW_ERROR_DLG_CAPTION" ),
402 tr( "DUMP_VIEW_ERROR_DLG_TEXT" ),
406 QString aSaveOp = "BMP";
407 QString aTypedFileExt = QFileInfo( aFileName ).extension( false ).lower();
409 if( aFileExt == "*.bmp" )
411 if( aTypedFileExt.isEmpty() )
415 else if( aFileExt == "*.png" )
416 if( aTypedFileExt.isEmpty() )
420 if( !anImage.save( aFileName, aSaveOp ) )
422 SUIT_MessageBox::error1( this,
423 tr( "DUMP_VIEW_ERROR_DLG_CAPTION" ),
424 tr( "DUMP_VIEW_ERROR_DLG_TEXT" ),
429 void GLViewer_ViewFrame::onViewPan()
431 myViewer->activateTransform( GLViewer_Viewer::Pan );
434 void GLViewer_ViewFrame::onViewZoom()
436 myViewer->activateTransform( GLViewer_Viewer::Zoom );
439 void GLViewer_ViewFrame::onViewFitAll()
441 myViewer->activateTransform( GLViewer_Viewer::FitAll );
444 void GLViewer_ViewFrame::onViewFitArea()
446 myViewer->activateTransform( GLViewer_Viewer::FitRect );
449 void GLViewer_ViewFrame::onViewFitSelect()
451 myViewer->activateTransform( GLViewer_Viewer::FitSelect );
454 void GLViewer_ViewFrame::onViewGlobalPan()
456 myViewer->activateTransform( GLViewer_Viewer::PanGlobal );
459 void GLViewer_ViewFrame::onViewRotate()
461 //myViewer->activateTransform( GLViewer_Viewer::Rotate );
464 void GLViewer_ViewFrame::onViewReset()
466 myViewer->activateTransform( GLViewer_Viewer::Reset );
469 //================================================================
470 // Function : mouseEvent
471 // Purpose : dispatches mouse events
472 //================================================================
473 void GLViewer_ViewFrame::mouseEvent( QMouseEvent* e )
477 case QEvent::MouseButtonPress:
478 emit mousePressed( this, e );
480 case QEvent::MouseButtonRelease:
481 emit mouseReleased( this, e );
483 case QEvent::MouseButtonDblClick:
484 emit mouseDoubleClicked( this, e );
486 case QEvent::MouseMove:
487 emit mouseMoving( this, e );
494 //================================================================
495 // Function : keyEvent
496 // Purpose : dispatches key events
497 //================================================================
498 void GLViewer_ViewFrame::keyEvent( QKeyEvent* e )
502 case QEvent::KeyPress:
503 emit keyPressed( this, e );
505 case QEvent::KeyRelease:
506 emit keyReleased( this, e );
513 //================================================================
514 // Function : wheelEvent
515 // Purpose : dispatches wheel events
516 //================================================================
517 void GLViewer_ViewFrame::wheelEvent( QWheelEvent* e )
522 emit wheeling( this, e );