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 <GLViewerAfx.h>
14 #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 <SUIT_MessageBox.h>
26 #include <qfiledialog.h>
34 GLViewer_ViewFrame::GLViewer_ViewFrame( SUIT_Desktop* d, GLViewer_Viewer* vw )
35 : SUIT_ViewWindow( d ),
39 QFrame* client = new QFrame( this );
40 setCentralWidget( client );
42 QBoxLayout* layout = new QHBoxLayout( client, 1, 1 );
43 layout->setAutoAdd( true );
45 GLViewer_ViewPort2d* vp = new GLViewer_ViewPort2d( client, this );
46 //vp->turnGrid( true );
47 //vp->turnCompass( true );
48 //vp->enablePopup( false );
50 setBackgroundColor( Qt::white );
52 myToolBar = new QToolBar(this);
53 myToolBar->setCloseMode(QDockWindow::Undocked);
54 myToolBar->setLabel(tr("LBL_TOOLBAR_LABEL"));
62 GLViewer_ViewFrame::~GLViewer_ViewFrame()
66 //================================================================
67 // Function : createActions
69 //================================================================
70 void GLViewer_ViewFrame::createActions()
72 if (!myActionsMap.isEmpty()) return;
73 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
77 aAction = new QAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_DUMP" ) ),
78 tr( "MNU_DUMP_VIEW" ), 0, this);
79 aAction->setStatusTip(tr("DSC_DUMP_VIEW"));
80 connect(aAction, SIGNAL(activated()), this, SLOT(onViewDump()));
81 myActionsMap[ DumpId ] = aAction;
84 aAction = new QAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITALL" ) ),
85 tr( "MNU_FITALL" ), 0, this);
86 aAction->setStatusTip(tr("DSC_FITALL"));
87 connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitAll()));
88 myActionsMap[ FitAllId ] = aAction;
91 aAction = new QAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITAREA" ) ),
92 tr( "MNU_FITRECT" ), 0, this);
93 aAction->setStatusTip(tr("DSC_FITRECT"));
94 connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitArea()));
95 myActionsMap[ FitRectId ] = aAction;
98 aAction = new QAction(tr("MNU_FITSELECT"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITSELECT" ) ),
99 tr( "MNU_FITSELECT" ), 0, this);
100 aAction->setStatusTip(tr("DSC_FITSELECT"));
101 connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitSelect()));
102 myActionsMap[ FitSelectId ] = aAction;
105 aAction = new QAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_ZOOM" ) ),
106 tr( "MNU_ZOOM_VIEW" ), 0, this);
107 aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
108 connect(aAction, SIGNAL(activated()), this, SLOT(onViewZoom()));
109 myActionsMap[ ZoomId ] = aAction;
112 aAction = new QAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_PAN" ) ),
113 tr( "MNU_PAN_VIEW" ), 0, this);
114 aAction->setStatusTip(tr("DSC_PAN_VIEW"));
115 connect(aAction, SIGNAL(activated()), this, SLOT(onViewPan()));
116 myActionsMap[ PanId ] = aAction;
119 aAction = new QAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_GLOBALPAN" ) ),
120 tr( "MNU_GLOBALPAN_VIEW" ), 0, this);
121 aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
122 connect(aAction, SIGNAL(activated()), this, SLOT(onViewGlobalPan()));
123 myActionsMap[ GlobalPanId ] = aAction;
125 aAction = new QAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_RESET" ) ),
126 tr( "MNU_RESET_VIEW" ), 0, this);
127 aAction->setStatusTip(tr("DSC_RESET_VIEW"));
128 connect(aAction, SIGNAL(activated()), this, SLOT(onViewReset()));
129 myActionsMap[ ResetId ] = aAction;
132 //================================================================
133 // Function : createToolBar
135 //================================================================
136 void GLViewer_ViewFrame::createToolBar()
138 myActionsMap[DumpId]->addTo(myToolBar);
140 SUIT_ToolButton* aScaleBtn = new SUIT_ToolButton(myToolBar);
141 aScaleBtn->AddAction(myActionsMap[FitAllId]);
142 aScaleBtn->AddAction(myActionsMap[FitRectId]);
143 aScaleBtn->AddAction(myActionsMap[FitSelectId]);
144 aScaleBtn->AddAction(myActionsMap[ZoomId]);
146 SUIT_ToolButton* aPanBtn = new SUIT_ToolButton(myToolBar);
147 aPanBtn->AddAction(myActionsMap[PanId]);
148 aPanBtn->AddAction(myActionsMap[GlobalPanId]);
150 myActionsMap[ResetId]->addTo(myToolBar);
154 Sets the viewport for this frame
156 void GLViewer_ViewFrame::setViewPort( GLViewer_ViewPort* vp )
163 disconnect( myVP, SIGNAL( vpDrawExternal( QPainter* ) ), this, SIGNAL( vfDrawExternal( QPainter* ) ) );
164 disconnect( myVP, SIGNAL( vpMouseEvent( QMouseEvent* ) ), this, SLOT( mouseEvent( QMouseEvent* ) ) );
165 disconnect( myVP, SIGNAL( vpKeyEvent( QKeyEvent* ) ), this, SLOT( keyEvent( QKeyEvent* ) ) );
166 disconnect( myVP, SIGNAL( vpWheelEvent( QWheelEvent* ) ), this, SLOT( wheelEvent( QWheelEvent* ) ) );
167 disconnect( myVP, SIGNAL( contextMenuRequested( QContextMenuEvent* ) ),
168 this, SIGNAL( contextMenuRequested( QContextMenuEvent* ) ) );
173 connect( myVP, SIGNAL( vpDrawExternal( QPainter* ) ), this, SIGNAL( vfDrawExternal( QPainter* ) ) );
174 connect( myVP, SIGNAL( vpMouseEvent( QMouseEvent* ) ), this, SLOT( mouseEvent( QMouseEvent* ) ) );
175 connect( myVP, SIGNAL( vpKeyEvent( QKeyEvent* ) ), this, SLOT( keyEvent( QKeyEvent* ) ) );
176 connect( myVP, SIGNAL( vpWheelEvent( QWheelEvent* ) ), this, SLOT( wheelEvent( QWheelEvent* ) ) );
177 connect( myVP, SIGNAL( contextMenuRequested( QContextMenuEvent* ) ),
178 this, SIGNAL( contextMenuRequested( QContextMenuEvent* ) ) );
183 Returns the viewport of this frame. [ public ]
185 GLViewer_ViewPort* GLViewer_ViewFrame::getViewPort() const
191 Set background of the viewport. [ public ]
193 void GLViewer_ViewFrame::setBackgroundColor( const QColor& color )
196 myVP->setBackgroundColor( color );
200 Returns background of the viewport. [ public ]
202 QColor GLViewer_ViewFrame::backgroundColor() const
205 return myVP->backgroundColor();
206 return QMainWindow::backgroundColor();
210 Sets the viewer for this view. [ public ]
212 void GLViewer_ViewFrame::setViewer( GLViewer_Viewer* v )
218 Returns the viewer of this view. [ public ]
220 GLViewer_Viewer* GLViewer_ViewFrame::getViewer() const
226 Returns the preferred view size. [ virtual public ]
228 QSize GLViewer_ViewFrame::sizeHint() const
230 QWidget* p = parentWidget();
231 if ( p && p->inherits( "QWorkspaceChild" ) )
232 p = p->parentWidget(); /* QWorkspaceChild: internal impl class in QWorkspace */
234 return QMainWindow::sizeHint();
235 return QSize( 9 * p->width() / 10 , 9 * p->height() / 10 );
239 Called by viewer's 'update()' method. Does nothing by default [ virtual public ]
241 void GLViewer_ViewFrame::onUpdate( int )
245 //#include <windows.h>
247 void GLViewer_ViewFrame::onViewDump()
249 GLViewer_Widget* aWidget = ((GLViewer_ViewPort2d*)myVP)->getGLWidget();
251 width = aWidget->width();
252 height = aWidget->height();
254 int imageSize = width*height*3;
255 unsigned char* imageBits = NULL;
257 int reserve_bytes = width % 4; //32 bits platform
258 imageSize = (width+reserve_bytes)*height*3;
259 imageBits = new unsigned char[imageSize];
267 HGLRC hglrc_old, hglrc;
271 hglrc_old = wglGetCurrentContext();
272 hdc_old = wglGetCurrentDC();
274 hdc = CreateCompatibleDC( hdc_old );
277 cout << "Can't create compatible DC. Last Error Code: " << GetLastError() << endl;
281 int sizeBmi = Standard_Integer( sizeof(BITMAPINFO) + sizeof(RGBQUAD)*3 );
282 PBITMAPINFO pBmi = (PBITMAPINFO)( new char[sizeBmi] );
283 ZeroMemory( pBmi, sizeBmi );
285 pBmi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); //sizeBmi
286 pBmi->bmiHeader.biWidth = width;
287 pBmi->bmiHeader.biHeight = height;
288 pBmi->bmiHeader.biPlanes = 1;
289 pBmi->bmiHeader.biBitCount = 24;
290 pBmi->bmiHeader.biCompression = BI_RGB;
293 hBmp = CreateDIBSection ( hdc, pBmi, DIB_RGB_COLORS, &ppvBits, NULL, 0 );
294 SelectObject ( hdc, hBmp );
297 PIXELFORMATDESCRIPTOR pfd;
298 ZeroMemory( &pfd, sizeof( PIXELFORMATDESCRIPTOR ) );
299 pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR );
301 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP;
302 pfd.iPixelType = PFD_TYPE_RGBA;
305 pfd.iLayerType = PFD_MAIN_PLANE;
307 int iPf = ChoosePixelFormat( hdc, &pfd);
310 if ( !DescribePixelFormat ( hdc, iPf, sizeof(PIXELFORMATDESCRIPTOR), &pfd ) )
312 cout << "Can't describe Pixel Format. Last Error Code: " << GetLastError() << endl;
315 if ( !SetPixelFormat(hdc, iPf, &pfd) )
317 cout << "Can't set Pixel Format. Last Error Code: " << GetLastError() << endl;
320 hglrc = wglCreateContext( hdc );
323 cout << "Can't create new GL Context. Last Error Code: " << GetLastError() << endl;
326 if( !wglMakeCurrent( hdc, hglrc) )
328 cout << "Can't make current new context!" << endl;
332 glViewport( 0, 0, width, height );
334 glMatrixMode( GL_PROJECTION );
336 GLfloat w_c = width / 2., h_c = height / 2.;
338 gluOrtho2D( -w_c, w_c, -h_c, h_c );
340 glMatrixMode( GL_MODELVIEW );
344 QColor aColor = ((GLViewer_ViewPort2d*)myVP)->backgroundColor();
345 glClearColor( ( GLfloat )aColor.red() / 255,
346 ( GLfloat )aColor.green() / 255,
347 ( GLfloat )aColor.blue() / 255,
350 aWidget->exportRepaint();
352 memset(&bi, 0, sizeof(BITMAPINFOHEADER));
353 bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
354 bi.bmiHeader.biPlanes = 1;
355 bi.bmiHeader.biBitCount = 24;
356 bi.bmiHeader.biHeight = -height;
357 bi.bmiHeader.biWidth = width;
358 bi.bmiHeader.biCompression = BI_RGB;
360 num = GetDIBits(hdc, hBmp, 0, height, imageBits, &bi, DIB_RGB_COLORS);
362 wglMakeCurrent( hdc_old, hglrc_old );
363 wglDeleteContext( hglrc );
369 unsigned int* aPix = NULL;
370 QImage anImage( width, height, 32 );
371 for( int i = 0; i < height; i++ )
373 memset( anImage.scanLine( i ), 0, sizeof(unsigned int)*width );
375 for( int j = 0; j < width; j++ )
377 pos = imageBits + i*width*3 + j*3 + reserve_bytes*i;
378 aPix = (unsigned int*)anImage.scanLine(i)+j;
379 *aPix = qRgb( *pos, *(pos+1), *(pos+2) );
385 QString aFilter( "*.bmp\n*.png" );
387 QFileDialog aFileDlg( QDir::current().absPath(), aFilter, this );
388 aFileDlg.setCaption( tr( "DUMP_VIEW_SAVE_FILE_DLG_CAPTION" ) );
389 aFileDlg.setMode( QFileDialog::AnyFile );
391 if( !aFileDlg.exec() )
394 QString aFileName = aFileDlg.selectedFile();
395 QString aFileExt = aFileDlg.selectedFilter();
397 if( aFileName.isEmpty() )
399 SUIT_MessageBox::error1( this,
400 tr( "DUMP_VIEW_ERROR_DLG_CAPTION" ),
401 tr( "DUMP_VIEW_ERROR_DLG_TEXT" ),
405 QString aSaveOp = "BMP";
406 QString aTypedFileExt = QFileInfo( aFileName ).extension( false ).lower();
408 if( aFileExt == "*.bmp" )
410 if( aTypedFileExt.isEmpty() )
414 else if( aFileExt == "*.png" )
415 if( aTypedFileExt.isEmpty() )
420 // if( !anImage.save( aFileName, aSaveOp ) )
422 if( !aWidget->grabFrameBuffer().save( aFileName, aSaveOp ) )
425 SUIT_MessageBox::error1( this,
426 tr( "DUMP_VIEW_ERROR_DLG_CAPTION" ),
427 tr( "DUMP_VIEW_ERROR_DLG_TEXT" ),
432 void GLViewer_ViewFrame::onViewPan()
434 myViewer->activateTransform( GLViewer_Viewer::Pan );
437 void GLViewer_ViewFrame::onViewZoom()
439 myViewer->activateTransform( GLViewer_Viewer::Zoom );
442 void GLViewer_ViewFrame::onViewFitAll()
444 myViewer->activateTransform( GLViewer_Viewer::FitAll );
447 void GLViewer_ViewFrame::onViewFitArea()
449 myViewer->activateTransform( GLViewer_Viewer::FitRect );
452 void GLViewer_ViewFrame::onViewFitSelect()
454 myViewer->activateTransform( GLViewer_Viewer::FitSelect );
457 void GLViewer_ViewFrame::onViewGlobalPan()
459 myViewer->activateTransform( GLViewer_Viewer::PanGlobal );
462 void GLViewer_ViewFrame::onViewRotate()
464 //myViewer->activateTransform( GLViewer_Viewer::Rotate );
467 void GLViewer_ViewFrame::onViewReset()
469 myViewer->activateTransform( GLViewer_Viewer::Reset );
472 //================================================================
473 // Function : mouseEvent
474 // Purpose : dispatches mouse events
475 //================================================================
476 void GLViewer_ViewFrame::mouseEvent( QMouseEvent* e )
480 case QEvent::MouseButtonPress:
481 emit mousePressed( this, e );
483 case QEvent::MouseButtonRelease:
484 emit mouseReleased( this, e );
486 case QEvent::MouseButtonDblClick:
487 emit mouseDoubleClicked( this, e );
489 case QEvent::MouseMove:
490 emit mouseMoving( this, e );
497 //================================================================
498 // Function : keyEvent
499 // Purpose : dispatches key events
500 //================================================================
501 void GLViewer_ViewFrame::keyEvent( QKeyEvent* e )
505 case QEvent::KeyPress:
506 emit keyPressed( this, e );
508 case QEvent::KeyRelease:
509 emit keyReleased( this, e );
516 //================================================================
517 // Function : wheelEvent
518 // Purpose : dispatches wheel events
519 //================================================================
520 void GLViewer_ViewFrame::wheelEvent( QWheelEvent* e )
525 emit wheeling( this, e );