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_Application.h>
21 #include <SUIT_Session.h>
22 #include <SUIT_ToolButton.h>
23 #include <SUIT_ResourceMgr.h>
24 #include <SUIT_Tools.h>
25 #include <QtxAction.h>
26 #include <SUIT_MessageBox.h>
36 GLViewer_ViewFrame::GLViewer_ViewFrame( SUIT_Desktop* d, GLViewer_Viewer* vw )
37 : SUIT_ViewWindow( d ),
41 QFrame* client = new QFrame( this );
42 setCentralWidget( client );
44 QBoxLayout* layout = new QHBoxLayout( client, 1, 1 );
45 layout->setAutoAdd( true );
47 GLViewer_ViewPort2d* vp = new GLViewer_ViewPort2d( client, this );
48 //vp->turnGrid( true );
49 //vp->turnCompass( true );
50 //vp->enablePopup( false );
52 setBackgroundColor( Qt::white );
54 myToolBar = new QToolBar(this);
55 myToolBar->setCloseMode(QDockWindow::Undocked);
56 myToolBar->setLabel(tr("LBL_TOOLBAR_LABEL"));
64 GLViewer_ViewFrame::~GLViewer_ViewFrame()
68 //================================================================
69 // Function : createActions
71 //================================================================
72 void GLViewer_ViewFrame::createActions()
74 if ( !myActionsMap.isEmpty() )
78 SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
81 aAction = new QtxAction(tr("MNU_DUMP_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_DUMP" ) ),
82 tr( "MNU_DUMP_VIEW" ), 0, this);
83 aAction->setStatusTip(tr("DSC_DUMP_VIEW"));
84 connect(aAction, SIGNAL(activated()), this, SLOT(onDumpView()));
85 myActionsMap[ DumpId ] = aAction;
88 aAction = new QtxAction(tr("MNU_FITALL"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITALL" ) ),
89 tr( "MNU_FITALL" ), 0, this);
90 aAction->setStatusTip(tr("DSC_FITALL"));
91 connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitAll()));
92 myActionsMap[ FitAllId ] = aAction;
95 aAction = new QtxAction(tr("MNU_FITRECT"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITAREA" ) ),
96 tr( "MNU_FITRECT" ), 0, this);
97 aAction->setStatusTip(tr("DSC_FITRECT"));
98 connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitArea()));
99 myActionsMap[ FitRectId ] = aAction;
102 aAction = new QtxAction(tr("MNU_FITSELECT"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_FITSELECT" ) ),
103 tr( "MNU_FITSELECT" ), 0, this);
104 aAction->setStatusTip(tr("DSC_FITSELECT"));
105 connect(aAction, SIGNAL(activated()), this, SLOT(onViewFitSelect()));
106 myActionsMap[ FitSelectId ] = aAction;
109 aAction = new QtxAction(tr("MNU_ZOOM_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_ZOOM" ) ),
110 tr( "MNU_ZOOM_VIEW" ), 0, this);
111 aAction->setStatusTip(tr("DSC_ZOOM_VIEW"));
112 connect(aAction, SIGNAL(activated()), this, SLOT(onViewZoom()));
113 myActionsMap[ ZoomId ] = aAction;
116 aAction = new QtxAction(tr("MNU_PAN_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_PAN" ) ),
117 tr( "MNU_PAN_VIEW" ), 0, this);
118 aAction->setStatusTip(tr("DSC_PAN_VIEW"));
119 connect(aAction, SIGNAL(activated()), this, SLOT(onViewPan()));
120 myActionsMap[ PanId ] = aAction;
123 aAction = new QtxAction(tr("MNU_GLOBALPAN_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_GLOBALPAN" ) ),
124 tr( "MNU_GLOBALPAN_VIEW" ), 0, this);
125 aAction->setStatusTip(tr("DSC_GLOBALPAN_VIEW"));
126 connect(aAction, SIGNAL(activated()), this, SLOT(onViewGlobalPan()));
127 myActionsMap[ GlobalPanId ] = aAction;
129 aAction = new QtxAction(tr("MNU_RESET_VIEW"), aResMgr->loadPixmap( "GLViewer", tr( "ICON_GL_RESET" ) ),
130 tr( "MNU_RESET_VIEW" ), 0, this);
131 aAction->setStatusTip(tr("DSC_RESET_VIEW"));
132 connect(aAction, SIGNAL(activated()), this, SLOT(onViewReset()));
133 myActionsMap[ ResetId ] = aAction;
136 //================================================================
137 // Function : createToolBar
139 //================================================================
140 void GLViewer_ViewFrame::createToolBar()
142 myActionsMap[DumpId]->addTo(myToolBar);
144 SUIT_ToolButton* aScaleBtn = new SUIT_ToolButton(myToolBar);
145 aScaleBtn->AddAction(myActionsMap[FitAllId]);
146 aScaleBtn->AddAction(myActionsMap[FitRectId]);
147 aScaleBtn->AddAction(myActionsMap[FitSelectId]);
148 aScaleBtn->AddAction(myActionsMap[ZoomId]);
150 SUIT_ToolButton* aPanBtn = new SUIT_ToolButton(myToolBar);
151 aPanBtn->AddAction(myActionsMap[PanId]);
152 aPanBtn->AddAction(myActionsMap[GlobalPanId]);
154 myActionsMap[ResetId]->addTo(myToolBar);
158 Sets the viewport for this frame
160 void GLViewer_ViewFrame::setViewPort( GLViewer_ViewPort* vp )
167 disconnect( myVP, SIGNAL( vpDrawExternal( QPainter* ) ), this, SIGNAL( vfDrawExternal( QPainter* ) ) );
168 disconnect( myVP, SIGNAL( vpMouseEvent( QMouseEvent* ) ), this, SLOT( mouseEvent( QMouseEvent* ) ) );
169 disconnect( myVP, SIGNAL( vpKeyEvent( QKeyEvent* ) ), this, SLOT( keyEvent( QKeyEvent* ) ) );
170 disconnect( myVP, SIGNAL(contextMenuRequested( QContextMenuEvent * )),
171 this, SIGNAL(contextMenuRequested( QContextMenuEvent * )) );
172 disconnect( myVP, SIGNAL( vpWheelEvent( QWheelEvent* ) ), this, SLOT( wheelEvent( QWheelEvent* ) ) );
177 connect( myVP, SIGNAL( vpDrawExternal( QPainter* ) ), this, SIGNAL( vfDrawExternal( QPainter* ) ) );
178 connect( myVP, SIGNAL( vpMouseEvent( QMouseEvent* ) ), this, SLOT( mouseEvent( QMouseEvent* ) ) );
179 connect( myVP, SIGNAL( vpKeyEvent( QKeyEvent* ) ), this, SLOT( keyEvent( QKeyEvent* ) ) );
180 connect( myVP, SIGNAL(contextMenuRequested( QContextMenuEvent * )),
181 this, SIGNAL(contextMenuRequested( QContextMenuEvent * )) );
182 connect( myVP, SIGNAL( vpWheelEvent( QWheelEvent* ) ), this, SLOT( wheelEvent( QWheelEvent* ) ) );
187 Returns the viewport of this frame. [ public ]
189 GLViewer_ViewPort* GLViewer_ViewFrame::getViewPort() const
195 Set background of the viewport. [ public ]
197 void GLViewer_ViewFrame::setBackgroundColor( const QColor& color )
200 myVP->setBackgroundColor( color );
204 Returns background of the viewport. [ public ]
206 QColor GLViewer_ViewFrame::backgroundColor() const
209 return myVP->backgroundColor();
210 return QMainWindow::backgroundColor();
214 Sets the viewer for this view. [ public ]
216 void GLViewer_ViewFrame::setViewer( GLViewer_Viewer* v )
222 Returns the viewer of this view. [ public ]
224 GLViewer_Viewer* GLViewer_ViewFrame::getViewer() const
230 Returns the preferred view size. [ virtual public ]
232 QSize GLViewer_ViewFrame::sizeHint() const
234 QWidget* p = parentWidget();
235 if ( p && p->inherits( "QWorkspaceChild" ) )
236 p = p->parentWidget(); /* QWorkspaceChild: internal impl class in QWorkspace */
238 return QMainWindow::sizeHint();
239 return QSize( 9 * p->width() / 10 , 9 * p->height() / 10 );
243 Called by viewer's 'update()' method. Does nothing by default [ virtual public ]
245 void GLViewer_ViewFrame::onUpdate( int )
249 QImage GLViewer_ViewFrame::dumpView()
251 GLViewer_Widget* aWidget = ((GLViewer_ViewPort2d*)myVP)->getGLWidget();
253 width = aWidget->width();
254 height = aWidget->height();
256 int imageSize = width*height*3;
257 unsigned char* imageBits = NULL;
259 int reserve_bytes = width % 4; //32 bits platform
260 imageSize = (width+reserve_bytes)*height*3;
261 imageBits = new unsigned char[imageSize];
269 HGLRC hglrc_old, hglrc;
273 hglrc_old = wglGetCurrentContext();
274 hdc_old = wglGetCurrentDC();
276 hdc = CreateCompatibleDC( hdc_old );
279 cout << "Can't create compatible DC. Last Error Code: " << GetLastError() << endl;
283 int sizeBmi = Standard_Integer( sizeof(BITMAPINFO) + sizeof(RGBQUAD)*3 );
284 PBITMAPINFO pBmi = (PBITMAPINFO)( new char[sizeBmi] );
285 ZeroMemory( pBmi, sizeBmi );
287 pBmi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); //sizeBmi
288 pBmi->bmiHeader.biWidth = width;
289 pBmi->bmiHeader.biHeight = height;
290 pBmi->bmiHeader.biPlanes = 1;
291 pBmi->bmiHeader.biBitCount = 24;
292 pBmi->bmiHeader.biCompression = BI_RGB;
295 hBmp = CreateDIBSection ( hdc, pBmi, DIB_RGB_COLORS, &ppvBits, NULL, 0 );
296 SelectObject ( hdc, hBmp );
299 PIXELFORMATDESCRIPTOR pfd;
300 ZeroMemory( &pfd, sizeof( PIXELFORMATDESCRIPTOR ) );
301 pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR );
303 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_BITMAP;
304 pfd.iPixelType = PFD_TYPE_RGBA;
307 pfd.iLayerType = PFD_MAIN_PLANE;
309 int iPf = ChoosePixelFormat( hdc, &pfd);
312 if ( !DescribePixelFormat ( hdc, iPf, sizeof(PIXELFORMATDESCRIPTOR), &pfd ) )
314 cout << "Can't describe Pixel Format. Last Error Code: " << GetLastError() << endl;
317 if ( !SetPixelFormat(hdc, iPf, &pfd) )
319 cout << "Can't set Pixel Format. Last Error Code: " << GetLastError() << endl;
322 hglrc = wglCreateContext( hdc );
325 cout << "Can't create new GL Context. Last Error Code: " << GetLastError() << endl;
328 if( !wglMakeCurrent( hdc, hglrc) )
330 cout << "Can't make current new context!" << endl;
334 glViewport( 0, 0, width, height );
336 glMatrixMode( GL_PROJECTION );
338 GLfloat w_c = width / 2., h_c = height / 2.;
340 gluOrtho2D( -w_c, w_c, -h_c, h_c );
342 glMatrixMode( GL_MODELVIEW );
346 QColor aColor = ((GLViewer_ViewPort2d*)myVP)->backgroundColor();
347 glClearColor( ( GLfloat )aColor.red() / 255,
348 ( GLfloat )aColor.green() / 255,
349 ( GLfloat )aColor.blue() / 255,
352 aWidget->exportRepaint();
354 memset(&bi, 0, sizeof(BITMAPINFOHEADER));
355 bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
356 bi.bmiHeader.biPlanes = 1;
357 bi.bmiHeader.biBitCount = 24;
358 bi.bmiHeader.biHeight = -height;
359 bi.bmiHeader.biWidth = width;
360 bi.bmiHeader.biCompression = BI_RGB;
362 num = GetDIBits(hdc, hBmp, 0, height, imageBits, &bi, DIB_RGB_COLORS);
364 wglMakeCurrent( hdc_old, hglrc_old );
365 wglDeleteContext( hglrc );
371 unsigned int* aPix = NULL;
372 QImage anImage( width, height, 32 );
373 for( int i = 0; i < height; i++ )
375 memset( anImage.scanLine( i ), 0, sizeof(unsigned int)*width );
377 for( int j = 0; j < width; j++ )
379 pos = imageBits + i*width*3 + j*3 + reserve_bytes*i;
380 aPix = (unsigned int*)anImage.scanLine(i)+j;
381 *aPix = qRgb( *pos, *(pos+1), *(pos+2) );
389 void GLViewer_ViewFrame::onViewPan()
391 myViewer->activateTransform( GLViewer_Viewer::Pan );
394 void GLViewer_ViewFrame::onViewZoom()
396 myViewer->activateTransform( GLViewer_Viewer::Zoom );
399 void GLViewer_ViewFrame::onViewFitAll()
401 myViewer->activateTransform( GLViewer_Viewer::FitAll );
404 void GLViewer_ViewFrame::onViewFitArea()
406 myViewer->activateTransform( GLViewer_Viewer::FitRect );
409 void GLViewer_ViewFrame::onViewFitSelect()
411 myViewer->activateTransform( GLViewer_Viewer::FitSelect );
414 void GLViewer_ViewFrame::onViewGlobalPan()
416 myViewer->activateTransform( GLViewer_Viewer::PanGlobal );
419 void GLViewer_ViewFrame::onViewRotate()
421 //myViewer->activateTransform( GLViewer_Viewer::Rotate );
424 void GLViewer_ViewFrame::onViewReset()
426 myViewer->activateTransform( GLViewer_Viewer::Reset );
429 //================================================================
430 // Function : mouseEvent
431 // Purpose : dispatches mouse events
432 //================================================================
433 void GLViewer_ViewFrame::mouseEvent( QMouseEvent* e )
437 case QEvent::MouseButtonPress:
438 emit mousePressed( this, e );
440 case QEvent::MouseButtonRelease:
441 emit mouseReleased( this, e );
443 case QEvent::MouseButtonDblClick:
444 emit mouseDoubleClicked( this, e );
446 case QEvent::MouseMove:
447 emit mouseMoving( this, e );
454 //================================================================
455 // Function : keyEvent
456 // Purpose : dispatches key events
457 //================================================================
458 void GLViewer_ViewFrame::keyEvent( QKeyEvent* e )
462 case QEvent::KeyPress:
463 emit keyPressed( this, e );
465 case QEvent::KeyRelease:
466 emit keyReleased( this, e );
473 //================================================================
474 // Function : wheelEvent
475 // Purpose : dispatches wheel events
476 //================================================================
477 void GLViewer_ViewFrame::wheelEvent( QWheelEvent* e )
482 emit wheeling( this, e );