NorMIT-nav  2023.01.05-dev+develop.0da12
An IGT application
cxViewContainer.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 #include "cxViewContainer.h"
13 
14 #include <QResizeEvent>
15 #include "vtkRenderWindow.h"
16 #include "vtkRenderer.h"
17 #include <QGridLayout>
18 #include "cxViewUtilities.h"
19 #include "cxViewContainerItem.h"
20 #include "cxTypeConversions.h"
21 #include "cxGLHelpers.h"
22 #include "cxOSXHelper.h"
23 #include "cxViewCache.h"
24 #include "cxLogger.h"
25 
26 namespace cx
27 {
28 
29 ViewContainer::ViewContainer(RenderWindowFactoryPtr factory, QWidget *parent, Qt::WindowFlags f) :
30  mRenderWindowFactory(factory),
31  QVTKWidget(parent, f),
32  mMouseEventTarget(NULL),
33  mRenderWindow(NULL)
34 {
35  mOffScreenRendering = false;
36  this->setContextMenuPolicy(Qt::CustomContextMenu);
37  connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(customContextMenuRequestedSlot(const QPoint &)));
38  mMTimeHash = 0;
39  mMouseEventTarget = NULL;
40  this->setLayout(new QGridLayout);
41  disableGLHiDPI(this->winId());
42 }
43 
45 {
46 }
47 
52 {
53  QLayoutItem *item;
54  while ((item = getGridLayout()->takeAt(0)) != 0)
55  {
56  ViewItem* viewItem = dynamic_cast<ViewItem*>(item);
57  delete viewItem;
58  }
60  this->setModified();
61  mMouseEventTarget = NULL;
62 }
63 
68 {
69  return dynamic_cast<QGridLayout*>(layout());
70 }
71 
72 void ViewContainer::paintEvent(QPaintEvent* event)
73 {
74  inherited_widget::paintEvent(event);
75  this->setModified();
76 }
77 
79 {
80  if (this->getGridLayout())
81  {
82  for (int i = 0; i < this->getGridLayout()->count(); ++i)
83  {
84  this->getViewItem(i)->getView()->setModified();
85  }
86  }
87  mMTimeHash = 0;
88 }
89 
91 {
92  return dynamic_cast<ViewItem*>(this->getGridLayout()->itemAt(index));
93 }
94 
99 ViewItem *ViewContainer::addView(QString uid, LayoutRegion region, QString name)
100 {
101  this->initializeRenderWindow();
102 
103  // Create a viewItem for this view
104  ViewItem *item = new ViewItem(uid, name, this, mRenderWindow, QRect());
105  if (getGridLayout())
106  getGridLayout()->addItem(item,
107  region.pos.row, region.pos.col,
108  region.span.row, region.span.col);
109  view_utils::setStretchFactors(this->getGridLayout(), region, 1);
110 
111  return item;
112 }
113 
115 {
116  this->clear();
117  mOffScreenRendering = on;
118 }
119 
121 {
122  return mOffScreenRendering;
123 }
124 
125 void ViewContainer::initializeRenderWindow()
126 {
127  if (mRenderWindow)
128  return;
129 
130  QString uid = QString("rw_oscr=%1").arg(mOffScreenRendering);
131 
132  bool renderWindowExists = mRenderWindowFactory->renderWindowExists(uid);
133 
134  mRenderWindow = mRenderWindowFactory->getRenderWindow(uid, mOffScreenRendering);
135  if(!renderWindowExists)
136  this->addBackgroundRenderer(mRenderWindow);
137  this->SetRenderWindow(mRenderWindow);
138  mRenderWindow->GetInteractor()->EnableRenderOff();
139 
140 
141 
142 // if (!mCachedRenderWindows.count(uid))
143 // {
145 // vtkRenderWindowPtr rw = mRenderWindowFactory->getRenderWindow(uid, mOffScreenRendering);
146 // this->addBackgroundRenderer(rw);
147 // mCachedRenderWindows[uid] = rw;
148 // }
149 
150 // // replace the previous renderwindow with one from the cache.
151 // // the old renderwindow is not hidden explicitly: is this a problem??
154 // mRenderWindow = mCachedRenderWindows[uid];
155 // this->SetRenderWindow(mRenderWindow);
156 // mRenderWindow->GetInteractor()->EnableRenderOff();
158 }
159 
160 void ViewContainer::addBackgroundRenderer(vtkRenderWindowPtr rw)
161 {
162  vtkRendererPtr renderer = vtkRendererPtr::New();
163  rw->AddRenderer(renderer);
164  renderer->SetViewport(0,0,1,1);
165  QColor background = palette().color(QPalette::Background);
166  renderer->SetBackground(background.redF(), background.greenF(), background.blueF());
167 }
168 
169 void ViewContainer::customContextMenuRequestedSlot(const QPoint& point)
170 {
171  ViewItem* item = this->findViewItem(point);
172  if (!item)
173  return;
174 
175  QWidget* sender = dynamic_cast<QWidget*>(this->sender());
176  QPoint pointGlobal = sender->mapToGlobal(point);
177 
178  item->customContextMenuRequestedGlobalSlot(pointGlobal);
179 }
180 
181 void ViewContainer::mouseMoveEvent(QMouseEvent* event)
182 {
183  inherited_widget::mouseMoveEvent(event);
184 
185  if (mMouseEventTarget)
186  {
187  QPoint p = this->convertToItemSpace(event->pos(), mMouseEventTarget);
188  mMouseEventTarget->mouseMoveSlot(p.x(), p.y(), event->buttons());
189  }
190 }
191 
192 void ViewContainer::mousePressEvent(QMouseEvent* event)
193 {
194  // special case for CustusX: when context menu is opened, mousereleaseevent is never called.
195  // this sets the render interactor in a zoom state after each menu call. This hack prevents
196  // the mouse press event in this case.
197  // NOTE: this doesnt seem to be the case in this class - investigate
198  if ((this->contextMenuPolicy() == Qt::CustomContextMenu) && event->buttons().testFlag(Qt::RightButton))
199  return;
200 
201  inherited_widget::mousePressEvent(event);
202 
203  mMouseEventTarget = this->findViewItem(event->pos());
204  if (mMouseEventTarget)
205  {
206  QPoint p = this->convertToItemSpace(event->pos(), mMouseEventTarget);
207  mMouseEventTarget->mousePressSlot(p.x(), p.y(), event->buttons());
208  }
209 }
210 
211 QPoint ViewContainer::convertToItemSpace(const QPoint &pos, ViewItem* item) const
212 {
213  QRect r = item->geometry();
214  QPoint retval(pos.x() - r.left(), pos.y() - r.top());
215  return retval;
216 }
217 
218 ViewItem* ViewContainer::findViewItem(const QPoint &pos)
219 {
220  for (int i = 0; getGridLayout() && i < getGridLayout()->count(); ++i)
221  {
222  ViewItem *item = this->getViewItem(i);
223  QRect r = item->geometry();
224  if (r.contains(pos))
225  return item;
226  }
227  return NULL;
228 }
229 
230 void ViewContainer::mouseReleaseEvent(QMouseEvent* event)
231 {
232  inherited_widget::mouseReleaseEvent(event);
233 
234  if (mMouseEventTarget)
235  {
236  QPoint p = this->convertToItemSpace(event->pos(), mMouseEventTarget);
237  mMouseEventTarget->mouseReleaseSlot(p.x(), p.y(), event->buttons());
238  mMouseEventTarget = NULL;
239  }
240 }
241 
242 void ViewContainer::focusInEvent(QFocusEvent* event)
243 {
244  inherited_widget::focusInEvent(event);
245 }
246 
247 void ViewContainer::wheelEvent(QWheelEvent* event)
248 {
249  inherited_widget::wheelEvent(event);
250 
251  ViewItem *item = this->findViewItem(event->pos());
252  if (item)
253  {
254  QPoint p = this->convertToItemSpace(event->pos(), item);
255  item->mouseWheelSlot(p.x(), p.y(),
256  event->delta(), event->orientation(), event->buttons());
257  }
258 }
259 
260 void ViewContainer::showEvent(QShowEvent* event)
261 {
262  inherited_widget::showEvent(event);
263 }
264 
266 {
267  // First, calculate if anything has changed
268  long hash = 0;
269  for (int i = 0; getGridLayout() && i < getGridLayout()->count(); ++i)
270  {
271  ViewItem *item = this->getViewItem(i);
272  hash += item->getView()->computeTotalMTime();
273  }
274  // Then, if anything has changed, render everything anew
275  if (hash != mMTimeHash)
276  {
277  this->doRender();
278  mMTimeHash = hash;
279 
280  QString msg("During rendering of ViewContainer");
282  }
283 }
284 
286 {
287  if (!mRenderWindow)
288  return;
289  this->getRenderWindow()->Render();
290 }
291 
292 void ViewContainer::resizeEvent( QResizeEvent *event)
293 {
294  inherited_widget::resizeEvent(event);
295  this->setModified();
296  this->getGridLayout()->update();
297 }
298 
299 
300 } /* namespace cx */
cxViewCache.h
cxOSXHelper.h
cxGLHelpers.h
cxLogger.h
cx::LayoutRegion::span
LayoutPosition span
size of region
Definition: cxLayoutData.h:46
cxViewContainerItem.h
vtkRenderWindowPtr
vtkSmartPointer< class vtkRenderWindow > vtkRenderWindowPtr
Definition: vtkForwardDeclarations.h:124
cx::ViewContainer::mMouseEventTarget
ViewItem * mMouseEventTarget
Definition: cxViewContainer.h:72
cx
Namespace for all CustusX production code.
Definition: cx_dev_group_definitions.h:13
report_gl_error_text
#define report_gl_error_text(text)
Definition: cxGLHelpers.h:29
cx::ViewContainer::getOffScreenRendering
virtual bool getOffScreenRendering() const
Definition: cxViewContainer.cpp:120
cx::ViewItem
Definition: cxViewContainerItem.h:38
cx::ViewContainer::addView
ViewItem * addView(QString uid, LayoutRegion region, QString name="")
Definition: cxViewContainer.cpp:99
cstring_cast
cstring_cast_Placeholder cstring_cast(const T &val)
Definition: cxTypeConversions.h:69
cx::LayoutPosition::col
int col
column
Definition: cxLayoutData.h:37
cx::ViewContainer::setModified
virtual void setModified()
Definition: cxViewContainer.cpp:78
cx::ViewItem::getView
ViewRepCollectionPtr getView()
Definition: cxViewContainerItem.h:43
cx::RenderWindowFactoryPtr
boost::shared_ptr< class RenderWindowFactory > RenderWindowFactoryPtr
Definition: cxForwardDeclarations.h:163
cxViewUtilities.h
cx::ViewContainer::getGridLayout
virtual QGridLayout * getGridLayout()
Definition: cxViewContainer.cpp:67
cx::ViewContainer::ViewContainer
ViewContainer(RenderWindowFactoryPtr factory, QWidget *parent=NULL, Qt::WindowFlags f=0)
Definition: cxViewContainer.cpp:29
cx::ViewContainer::mRenderWindow
vtkRenderWindowPtr mRenderWindow
Definition: cxViewContainer.h:73
cxTypeConversions.h
cx::view_utils::setStretchFactors
void setStretchFactors(QGridLayout *layout, LayoutRegion region, int stretchFactor)
Definition: cxViewUtilities.cpp:20
cx::ViewContainer::clear
virtual void clear()
Definition: cxViewContainer.cpp:51
cx::ViewContainer::mMTimeHash
unsigned long mMTimeHash
sum of all MTimes in objects rendered
Definition: cxViewContainer.h:74
cx::ViewContainer::getViewItem
ViewItem * getViewItem(int index)
Definition: cxViewContainer.cpp:90
cx::LayoutRegion
Definition: cxLayoutData.h:40
cx::ViewContainer::setOffScreenRenderingAndClear
virtual void setOffScreenRenderingAndClear(bool on)
Definition: cxViewContainer.cpp:114
cx::ViewItem::mouseReleaseSlot
void mouseReleaseSlot(int x, int y, Qt::MouseButtons buttons)
Definition: cxViewContainerItem.h:72
cx::ViewContainer::doRender
virtual void doRender()
Definition: cxViewContainer.cpp:285
cx::LayoutPosition::row
int row
row
Definition: cxLayoutData.h:36
cx::ViewContainer::renderAll
void renderAll()
Use this function to render all views at once. Do not call render on each view.
Definition: cxViewContainer.cpp:265
cx::LayoutData::MaxGridSize
static const int MaxGridSize
Definition: cxLayoutData.h:82
cx::LayoutRegion::pos
LayoutPosition pos
start position of region
Definition: cxLayoutData.h:45
vtkRendererPtr
vtkSmartPointer< class vtkRenderer > vtkRendererPtr
Definition: vtkForwardDeclarations.h:122
cx::ViewItem::mouseMoveSlot
void mouseMoveSlot(int x, int y, Qt::MouseButtons buttons)
Definition: cxViewContainerItem.h:70
cxViewContainer.h
cx::ViewContainer::~ViewContainer
virtual ~ViewContainer()
Definition: cxViewContainer.cpp:44
cx::ViewContainer::getRenderWindow
vtkRenderWindowPtr getRenderWindow()
Definition: cxViewContainer.h:55
cx::ViewItem::mousePressSlot
void mousePressSlot(int x, int y, Qt::MouseButtons buttons)
Definition: cxViewContainerItem.h:71