1 /*=========================================================================
2 
3 Program:   Visualization Toolkit
4 Module:    TestWin32QVTKWidget.cxx
5 
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 // Tests behavior of vtkWin32OpenGLRenderWindow under a QT Context.
16 // @Note
17 // opengl startup behaves differently when running
18 // on a build server. This test tries to exercise areas that have
19 // been known to fail but only in a local build. I.e. one cannot
20 // trust the dashboard entry for this test unfortunately.
21 
22 
23 #include "vtkSmartPointer.h"
24 #include "QVTKWidget.h"
25 #include "vtkWin32OpenGLRenderWindow.h"
26 #include "vtkNew.h"
27 #include "vtkRenderer.h"
28 
29 #include <QPointer>
30 #include <QDockWidget>
31 #include <QTabWidget>
32 #include <QEvent>
33 #include <QApplication>
34 #include <QMainWindow>
35 
36 #define TOKEN_TO_STRING(TOK) # TOK
37 #define STRINGIZE_TOKEN(TOK) TOKEN_TO_STRING(TOK)
38 #define PRINT_AND_EVAL(X) {std::string fnc=__FUNCTION__;std::cout<<fnc<<": "<<STRINGIZE_TOKEN(X)<<"="<<X<<std::endl;std::cout.flush();}
39 
40 #define fail(msg) \
41   std::cout << msg << std::endl; \
42   return EXIT_FAILURE
43 
flushQtEvents()44 void flushQtEvents()
45 {
46   QApplication::sendPostedEvents( );
47   QApplication::processEvents(QEventLoop::AllEvents,10);
48 }
49 
initializeWidget(QWidget * arg)50 void initializeWidget(QWidget* arg)
51 {
52   arg->setGeometry(20,20,640,480);
53   arg->show();
54   flushQtEvents();
55 }
56 
57 template <typename WidgetType1,typename WidgetType2=WidgetType1>
58 struct QVTKWidgetInsideQWidgets
59 {
QVTKWidgetInsideQWidgetsQVTKWidgetInsideQWidgets60   QVTKWidgetInsideQWidgets() : widget1(0), widget2(0), mainWindow(0)
61   {
62     renderer->SetBackground(1.0,0.0,0.8);
63     renderer->SetBackground2(0.5,0.5,0.5);
64     renderer->SetGradientBackground(true);
65     glwin->AddRenderer(renderer);
66   }
67 
~QVTKWidgetInsideQWidgetsQVTKWidgetInsideQWidgets68   ~QVTKWidgetInsideQWidgets()
69   {
70     widget1.data()->deleteLater();
71     widget2.data()->deleteLater();
72     if(mainWindow && !mainWindow->parent())
73       delete mainWindow;
74     //delete widget2;
75   }
76 
spawnSubwidgetQVTKWidgetInsideQWidgets77   QVTKWidget* spawnSubwidget( QTabWidget* tabWidget,QVTKWidget* qvtk=nullptr)
78   {
79     if(!mainWindow)
80       mainWindow = new QMainWindow();
81     tabWidget->setParent(mainWindow);
82     mainWindow->setCentralWidget(tabWidget);
83     if(!qvtk)
84       qvtk = new QVTKWidget();
85     qvtk->setMinimumSize(600,400);
86     tabWidget->addTab(qvtk, "qvtk_widget");
87     qvtk->setParent(tabWidget);
88     return qvtk;
89   }
90 
spawnSubwidgetQVTKWidgetInsideQWidgets91   QVTKWidget* spawnSubwidget(QMainWindow* mainWin,QVTKWidget* qvtk = nullptr)
92   {
93     mainWindow       = mainWin;
94     if (!qvtk)
95       qvtk = new QVTKWidget(mainWindow);
96 
97     qvtk->setMinimumSize(600, 400);
98     mainWindow->setCentralWidget(qvtk);
99     return qvtk;
100   }
101 
spawnSubwidgetQVTKWidgetInsideQWidgets102   QVTKWidget* spawnSubwidget(QDockWidget* dock,QVTKWidget* qvtk = nullptr)
103   {
104     if (!mainWindow)
105       mainWindow = new QMainWindow();
106     dock->setParent(mainWindow);
107     qvtk = new QVTKWidget(dock);
108     qvtk->setMinimumSize(600, 400);
109     dock->setWidget(qvtk);
110     return qvtk;
111   }
112 
runQVTKWidgetInsideQWidgets113   int run()
114   {
115     //auto window = std::make_unique<QMainWindow>();
116     widget1            = new WidgetType1();
117     initializeWidget(widget1);
118     QVTKWidget* qvtk   = spawnSubwidget( widget1 );
119 
120     qvtk->SetRenderWindow(glwin);
121 
122     PRINT_AND_EVAL("BEFORE RENDER:" << glwin->ReportCapabilities());
123     glwin->Render();
124     PRINT_AND_EVAL("AFTER RENDER1:" << glwin->ReportCapabilities());
125 
126     flushQtEvents();
127     widget2 = new WidgetType2();
128     initializeWidget(widget2);
129     QVTKWidget* qvtk1_ref = spawnSubwidget( widget2, qvtk );
130 
131     qvtk1_ref->GetRenderWindow()->Render();
132 
133     PRINT_AND_EVAL("AFTER RENDER2:" << glwin->ReportCapabilities());
134     flushQtEvents();
135     return EXIT_SUCCESS;
136   }
137 
138   QPointer<WidgetType1>               widget1;
139   QPointer<WidgetType2>               widget2;
140   QPointer<QMainWindow>               mainWindow;
141   vtkNew<vtkWin32OpenGLRenderWindow>  glwin;
142   vtkNew<vtkRenderer>                 renderer;
143 };
144 
TestWin32QVTKWidget(int argc,char * argv[])145 int TestWin32QVTKWidget(int argc, char* argv[])
146 {
147 
148   QApplication app(argc, argv);
149 
150   if( EXIT_SUCCESS != QVTKWidgetInsideQWidgets<QMainWindow>().run() )
151     return EXIT_FAILURE;
152 
153   if (EXIT_SUCCESS != QVTKWidgetInsideQWidgets<QMainWindow,QTabWidget>().run())
154     return EXIT_FAILURE;
155 
156   if (EXIT_SUCCESS != QVTKWidgetInsideQWidgets<QMainWindow,QDockWidget>().run())
157     return EXIT_FAILURE;
158 
159   return EXIT_SUCCESS;
160 }
161