CustusX  15.3.4-beta
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 #include "cxViewContainer.h"
34 
35 #include <QResizeEvent>
36 #include "vtkRenderWindow.h"
37 #include "vtkRenderer.h"
38 #include <QGridLayout>
39 #include "cxViewUtilities.h"
40 #include "cxViewContainerItem.h"
41 
42 namespace cx
43 {
44 
45 ViewContainer::ViewContainer(QWidget *parent, Qt::WindowFlags f) :
46  QVTKWidget(parent, f),
47  mMouseEventTarget(NULL)
48 {
49  this->setContextMenuPolicy(Qt::CustomContextMenu);
50  connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(customContextMenuRequestedSlot(const QPoint &)));
51  mMTimeHash = 0;
52  mMouseEventTarget = NULL;
53  this->setLayout(new QGridLayout);
54 }
55 
57 {
58 }
59 
64 {
65  QLayoutItem *item;
66  while ((item = getGridLayout()->takeAt(0)) != 0)
67  {
68  ViewItem* viewItem = dynamic_cast<ViewItem*>(item);
69  delete viewItem;
70  }
71  view_utils::setStretchFactors(this->getGridLayout(), LayoutRegion(0, 0, 10, 10), 0);
72  this->setModified();
73  mMouseEventTarget = NULL;
74 }
75 
80 {
81  return (QGridLayout*) layout();
82 }
83 
84 void ViewContainer::paintEvent(QPaintEvent* event)
85 {
86  inherited_widget::paintEvent(event);
87  this->setModified();
88 }
89 
91 {
92  if (this->getGridLayout())
93  {
94  for (int i = 0; i < this->getGridLayout()->count(); ++i)
95  {
96  this->getViewItem(i)->getView()->setModified();
97  }
98  }
99  mMTimeHash = 0;
100 }
101 
103 {
104  return dynamic_cast<ViewItem*>(this->getGridLayout()->itemAt(index));
105 }
106 
111 ViewItem *ViewContainer::addView(QString uid, LayoutRegion region, QString name)
112 {
113  this->initializeRenderWindow();
114 
115  // Create a viewItem for this view
116  ViewItem *item = new ViewItem(uid, name, this, mRenderWindow, QRect());
117  if (getGridLayout())
118  getGridLayout()->addItem(item,
119  region.pos.row, region.pos.col,
120  region.span.row, region.span.col);
121  view_utils::setStretchFactors(this->getGridLayout(), region, 1);
122 
123  return item;
124 }
125 
126 void ViewContainer::initializeRenderWindow()
127 {
128  if (mRenderWindow)
129  return;
130 
131  mRenderWindow = vtkRenderWindowPtr::New();
132  this->SetRenderWindow(mRenderWindow);
133  mRenderWindow->GetInteractor()->EnableRenderOff();
134 
135  this->addBackgroundRenderer();
136 }
137 
138 void ViewContainer::addBackgroundRenderer()
139 {
140  vtkRendererPtr renderer = vtkRendererPtr::New();
141  mRenderWindow->AddRenderer(renderer);
142  renderer->SetViewport(0,0,1,1);
143  QColor background = palette().color(QPalette::Background);
144  renderer->SetBackground(background.redF(), background.greenF(), background.blueF());
145 }
146 
147 void ViewContainer::customContextMenuRequestedSlot(const QPoint& point)
148 {
149  ViewItem* item = this->findViewItem(point);
150  if (!item)
151  return;
152 
153  QWidget* sender = dynamic_cast<QWidget*>(this->sender());
154  QPoint pointGlobal = sender->mapToGlobal(point);
155 
156  item->customContextMenuRequestedGlobalSlot(pointGlobal);
157 }
158 
159 void ViewContainer::mouseMoveEvent(QMouseEvent* event)
160 {
161  inherited_widget::mouseMoveEvent(event);
162 
163  if (mMouseEventTarget)
164  {
165  QPoint p = this->convertToItemSpace(event->pos(), mMouseEventTarget);
166  mMouseEventTarget->mouseMoveSlot(p.x(), p.y(), event->buttons());
167  }
168 }
169 
170 void ViewContainer::mousePressEvent(QMouseEvent* event)
171 {
172  // special case for CustusX: when context menu is opened, mousereleaseevent is never called.
173  // this sets the render interactor in a zoom state after each menu call. This hack prevents
174  // the mouse press event in this case.
175  // NOTE: this doesnt seem to be the case in this class - investigate
176  if ((this->contextMenuPolicy() == Qt::CustomContextMenu) && event->buttons().testFlag(Qt::RightButton))
177  return;
178 
179  inherited_widget::mousePressEvent(event);
180 
181  mMouseEventTarget = this->findViewItem(event->pos());
182  if (mMouseEventTarget)
183  {
184  QPoint p = this->convertToItemSpace(event->pos(), mMouseEventTarget);
185  mMouseEventTarget->mousePressSlot(p.x(), p.y(), event->buttons());
186  }
187 }
188 
189 QPoint ViewContainer::convertToItemSpace(const QPoint &pos, ViewItem* item) const
190 {
191  QRect r = item->geometry();
192  QPoint retval(pos.x() - r.left(), pos.y() - r.top());
193  return retval;
194 }
195 
196 ViewItem* ViewContainer::findViewItem(const QPoint &pos)
197 {
198  for (int i = 0; getGridLayout() && i < getGridLayout()->count(); ++i)
199  {
200  ViewItem *item = this->getViewItem(i);
201  QRect r = item->geometry();
202  if (r.contains(pos))
203  return item;
204  }
205  return NULL;
206 }
207 
208 void ViewContainer::mouseReleaseEvent(QMouseEvent* event)
209 {
210  inherited_widget::mouseReleaseEvent(event);
211 
212  if (mMouseEventTarget)
213  {
214  QPoint p = this->convertToItemSpace(event->pos(), mMouseEventTarget);
215  mMouseEventTarget->mouseReleaseSlot(p.x(), p.y(), event->buttons());
216  mMouseEventTarget = NULL;
217  }
218 }
219 
220 void ViewContainer::focusInEvent(QFocusEvent* event)
221 {
222  inherited_widget::focusInEvent(event);
223 }
224 
225 void ViewContainer::wheelEvent(QWheelEvent* event)
226 {
227  inherited_widget::wheelEvent(event);
228 
229  ViewItem *item = this->findViewItem(event->pos());
230  if (item)
231  {
232  QPoint p = this->convertToItemSpace(event->pos(), item);
233  item->mouseWheelSlot(p.x(), p.y(),
234  event->delta(), event->orientation(), event->buttons());
235  }
236 }
237 
238 void ViewContainer::showEvent(QShowEvent* event)
239 {
240  inherited_widget::showEvent(event);
241 }
242 
244 {
245  // First, calculate if anything has changed
246  long hash = 0;
247  for (int i = 0; getGridLayout() && i < getGridLayout()->count(); ++i)
248  {
249  ViewItem *item = this->getViewItem(i);
250  hash += item->getView()->computeTotalMTime();
251  }
252  // Then, if anything has changed, render everything anew
253  if (hash != mMTimeHash)
254  {
255  this->doRender();
256  mMTimeHash = hash;
257  }
258 }
259 
261 {
262  this->getRenderWindow()->Render();
263 }
264 
265 void ViewContainer::resizeEvent( QResizeEvent *event)
266 {
267  inherited_widget::resizeEvent(event);
268  this->setModified();
269  this->getGridLayout()->update();
270 }
271 
272 
273 } /* namespace cx */
virtual void doRender()
LayoutPosition span
size of region
Definition: cxLayoutData.h:67
void mouseReleaseSlot(int x, int y, Qt::MouseButtons buttons)
ViewContainer(QWidget *parent=NULL, Qt::WindowFlags f=0)
ViewItem * addView(QString uid, LayoutRegion region, QString name="")
void mousePressSlot(int x, int y, Qt::MouseButtons buttons)
vtkSmartPointer< class vtkRenderer > vtkRendererPtr
ViewItem * getViewItem(int index)
vtkRenderWindowPtr getRenderWindow()
unsigned long mMTimeHash
sum of all MTimes in objects rendered
void mouseMoveSlot(int x, int y, Qt::MouseButtons buttons)
void setStretchFactors(QGridLayout *layout, LayoutRegion region, int stretchFactor)
virtual void setModified()
void renderAll()
Use this function to render all views at once. Do not call render on each view.
virtual void clear()
LayoutPosition pos
start position of region
Definition: cxLayoutData.h:66
virtual QGridLayout * getGridLayout()
ViewRepCollectionPtr getView()
vtkRenderWindowPtr mRenderWindow
ViewItem * mMouseEventTarget