Biomedical Image Analysis Library
The Biomedical Image Analysis Library is a poweful tool for developers, physicians, researchers, engineers, and so on.
imageviewer.cpp
Go to the documentation of this file.
1 #include <QDebug>
2 #include <QEvent>
3 #include <QGraphicsSceneMouseEvent>
4 #include <QGraphicsView>
5 #include <QGridLayout>
6 #include <iostream>
7 
8 #include "Common.hpp"
9 #include "controller.h"
10 #include "defaulttool.h"
11 #include "graphicsscene.h"
12 #include "imageviewer.h"
13 #include "imagewidget.h"
14 
15 ImageViewer::ImageViewer(QWidget *parent) : QWidget(parent) {
16  m_controller = nullptr;
17  for (size_t i = 0; i < views.size(); ++i) {
18  views[i] = new ImageWidget(this);
19  views[i]->hideControls();
20  getScene(i)->installEventFilter(this);
21  views[i]->setViewNumber(i);
22  connect(views.at(i), &ImageWidget::dropImage, this, &ImageViewer::dropImage);
23  connect(views.at(i), &ImageWidget::dropFolder, this, &ImageViewer::dropFolder);
24  }
25  layout = new QGridLayout(this);
26  layout->setVerticalSpacing(0);
27  layout->setHorizontalSpacing(0);
28  layout->setMargin(0);
29  setGridLayout();
30  QPalette p(palette());
31  p.setColor(QPalette::Background, Qt::black);
32  setAutoFillBackground(true);
33  setPalette(p);
34  dragging = false;
35 }
36 
38 
39 void ImageViewer::setViewBgColor(const QColor &color) {
40  for (ImageWidget *view : views) {
41  view->setViewBgColor(color);
42  }
43 }
44 
46  m_controller = value;
47  connect(m_controller, &Controller::currentImageChanged, this, &ImageViewer::changeImage);
48  connect(m_controller, &Controller::imageUpdated, this, &ImageViewer::updateViews);
49  /* connect( this, &ImageViewer::mouseClicked, controller, &Controller::changeOthersSlices ); */
50  for (ImageWidget *view : views) {
51  connect(view, &ImageWidget::sliceChanged, m_controller, &Controller::setCurrentSlice);
52  connect(view, &ImageWidget::sliceChanged, this, &ImageViewer::sliceChanged);
53  connect(view, &ImageWidget::rotate, m_controller, &Controller::rotate90);
54  connect(view, &ImageWidget::fliph, m_controller, &Controller::flipH);
55  connect(view, &ImageWidget::flipv, m_controller, &Controller::flipV);
56  }
57  for (size_t axis = 0; axis < 4; ++axis) {
58  getScene(axis)->addItem(m_controller->getPixmapItem(axis));
59  getScene(axis)->addItem(m_controller->getLabelItem(axis));
60  }
61 }
62 
63 Controller *ImageViewer::controller() const { return (m_controller); }
64 
65 void ImageViewer::updateViews() {
66  COMMENT("ImageViewer::updateViews", 2);
67  if (!m_controller) {
68  return;
69  }
70  GuiImage *img = m_controller->currentImage();
71  if (!img) {
72  return;
73  }
74  for (size_t axis = 0; axis < 4; ++axis) {
75  views[axis]->setSlice(img->currentSlice(axis));
76  getScene(axis)->setOverlay(m_controller->currentFormat()->overlay());
77  }
78 }
79 
80 void ImageViewer::changeImage() {
81  COMMENT("ImageViewer::changeImage", 2);
82  GuiImage *img = m_controller->currentImage();
83  if (img) {
84  if (img->tools.empty()) {
85  img->tools.append(new DefaultTool(img, this));
86  }
87  img->getIntersection(0);
88  DisplayFormat *format = m_controller->currentFormat();
89  for (size_t axis = 0; axis < 4; ++axis) {
90  getScene(axis)->setOverlay(false);
91  getScene(axis)->setOverlayPen(format->overlayColor());
92 // getScene(axis)->setOverlayPos(QPointF(100,100));
93 
94  if (format->hasViewerControls()) {
95  views[axis]->setRange(0, img->depth(axis) - 1);
96  views[axis]->setSlice(img->currentSlice(axis));
97  views[axis]->showControls();
98  } else {
99  views[axis]->hideControls();
100  }
101  }
102  if (format->modality() == Modality::RGB2D) {
103  getScene(1)->setOverlayPen(QPen(Qt::green));
104  getScene(2)->setOverlayPen(QPen(Qt::red));
105  getScene(3)->setOverlayPen(QPen(Qt::yellow));
106  }
107  setLayoutType(format->currentLayout());
108  setViewMode(format->currentViews());
109  for (size_t axis = 0; axis < 4; ++axis) {
110 // DefaultTool *tool = dynamic_cast<DefaultTool *>(img->tools[0]);
111 // tool->updateOverlay( overlaypos, axis );
112  if (m_controller) {
113  QRectF r = m_controller->getPixmapItem(axis)->boundingRect();
114  getScene(axis)->setSceneRect(r);
115  QGraphicsView *view = views[axis]->graphicsView();
116  view->fitInView(m_controller->getPixmapItem(axis), Qt::KeepAspectRatio);
117  }
118  }
119  updateViews();
120  }
121 }
122 
123 void ImageViewer::setLayoutType(Layout layout) {
124  switch (layout) {
125  case Layout::GRID: {
126  setGridLayout();
127  break;
128  }
129  case Layout::HORIZONTAL: {
130  setHorizontalLayout();
131  break;
132  }
133  case Layout::VERTICAL: {
134  setVerticalLayout();
135  break;
136  }
137  }
138 }
139 
140 void ImageViewer::getNewLayout() {
141  for (ImageWidget *view : views) {
142  layout->removeWidget(view);
143  }
144  updateViews();
145 }
146 
147 void ImageViewer::setGridLayout() {
148  COMMENT("Set grid layout.", 0)
149  getNewLayout();
150  layout->addWidget(views[0], 0, 0);
151  layout->addWidget(views[1], 0, 1);
152  layout->addWidget(views[2], 1, 0);
153  layout->addWidget(views[3], 1, 1);
154 
155  updateViews();
156 }
157 
158 void ImageViewer::setHorizontalLayout() {
159  COMMENT("Set horizontal layout.", 0)
160  getNewLayout();
161  layout->addWidget(views[0], 0, 0);
162  layout->addWidget(views[1], 0, 1);
163  layout->addWidget(views[2], 0, 2);
164  layout->addWidget(views[3], 0, 3);
165 
166  updateViews();
167 }
168 
169 void ImageViewer::setVerticalLayout() {
170  COMMENT("Set vertical layout.", 0)
171  getNewLayout();
172  layout->addWidget(views[0], 0, 0);
173  layout->addWidget(views[1], 1, 0);
174  layout->addWidget(views[2], 2, 0);
175  layout->addWidget(views[3], 3, 0);
176 
177  updateViews();
178 }
179 
180 void ImageViewer::hideViews() {
181  for (ImageWidget *view : views) {
182  view->hide();
183  }
184  updateViews();
185 }
186 
187 void ImageViewer::showViews() {
188  for (ImageWidget *view : views) {
189  view->show();
190  }
191  updateViews();
192 }
193 
194 void ImageViewer::setViewMode(Views view) {
195  hideViews();
196  views[0]->setVisible((int)view & (int)Views::SHOW0);
197  views[1]->setVisible((int)view & (int)Views::SHOW1);
198  views[2]->setVisible((int)view & (int)Views::SHOW2);
199  views[3]->setVisible((int)view & (int)Views::SHOW3);
200  updateViews();
201 }
202 
203 void ImageViewer::sliceChanged(size_t axis, size_t slice) {
204  if (m_controller->currentImage()) {
205  Tool *tool = m_controller->currentImage()->currentTool();
206  if (tool) {
207  tool->sliceChanged(axis, slice);
208  }
209  }
210 }
211 
212 void ImageViewer::resizeEvent(QResizeEvent *) { changeImage(); }
213 
214 bool ImageViewer::eventFilter(QObject *obj, QEvent *evt) {
215  QGraphicsSceneMouseEvent *mouseEvt = dynamic_cast<QGraphicsSceneMouseEvent *>(evt);
216  size_t axis = 0;
217  for (size_t scn = 1; scn < views.size(); ++scn) {
218  if (obj == views[scn]->scene()) {
219  axis = scn;
220  }
221  }
222  if (mouseEvt) {
223  Tool *tool = m_controller->currentImage()->currentTool();
224  QPointF scnPos = mouseEvt->scenePos();
225  if (mouseEvt->type() == QEvent::GraphicsSceneMouseMove) {
226  /* qDebug() << "MouseEvt = " << scnPos; */
227  if (dragging && (timer.elapsed() > 25)) {
228  timer.restart();
229  emit mouseDragged(scnPos, mouseEvt->buttons(), axis);
230  if (tool) {
231  tool->mouseDragged(scnPos, mouseEvt->buttons(), axis);
232  }
233  }
234  if (tool) {
235  tool->mouseMoved(scnPos, axis);
236  }
237  emit mouseMoved(scnPos, axis);
238  } else if (mouseEvt->type() == QEvent::GraphicsSceneMousePress) {
239  /* qDebug() << "MouseEvt = " << scnPos; */
240  if (mouseEvt->button() == Qt::LeftButton) {
241  dragging = true;
242  timer.restart();
243  }
244  emit mouseClicked(scnPos, mouseEvt->buttons(), axis);
245  if (tool) {
246  tool->mouseClicked(scnPos, mouseEvt->buttons(), axis);
247  }
248  } else if (mouseEvt->type() == QEvent::GraphicsSceneMouseRelease) {
249  if (mouseEvt->button() == Qt::LeftButton) {
250  dragging = false;
251  }
252  emit mouseReleased(scnPos, mouseEvt->buttons(), axis);
253  if (tool) {
254  tool->mouseReleased(scnPos, mouseEvt->buttons(), axis);
255  }
256  }
257  }
258  return (QWidget::eventFilter(obj, evt));
259 }
260 
262  if (axis > views.size()) {
263  throw std::out_of_range(BIAL_ERROR(QString("Invalid axis, expected < %1.").arg(views.size()).toStdString()));
264  }
265  return (views[axis]->scene());
266 }
void mouseClicked(QPointF pt, Qt::MouseButtons buttons, size_t axis)
void setOverlayPen(const QPen &overlayPen)
void mouseReleased(QPointF pt, Qt::MouseButtons buttons, size_t axis)
void dropFolder(const QString &folderPath)
Tool * currentTool()
currentTool returns the current Tool.
Definition: guiimage.cpp:150
bool eventFilter(QObject *obj, QEvent *evt)
ImageViewer(QWidget *parent=0)
Definition: imageviewer.cpp:15
Modality modality() const
void flipv(size_t viewNbr)
Definition: tool.h:10
virtual void sliceChanged(size_t axis, size_t slice)=0
void sliceChanged(size_t viewNbr, size_t slice)
#define BIAL_ERROR(exp)
Use BIAL_ERROR to compose runtime error messages. Note that ERROR generates a string, instead of a stream, because it is better to throw an exception, rather than exiting the program. This way, the exception may be threated by a higher level program, like an user IDE.
Definition: Common.hpp:161
DisplayFormat * currentFormat()
currentFormat returns the modality of current image.
Definition: controller.cpp:230
The GuiImage class is a bridge to the Bial::Image data structure to the QImage data structure...
Definition: guiimage.h:20
void setViewBgColor(const QColor &color)
Definition: imageviewer.cpp:39
void setCurrentSlice(size_t view, size_t slice)
setCurrentSlice is called by the imageViewer when the slider or the spinbox have theis values updated...
Definition: controller.cpp:165
Content: Commonly used macros, types, static variables and functions. Description: Some macros used...
void fliph(size_t viewNbr)
void rotate90(size_t view)
rotate90 rotates a view in 90 degrees.
Definition: controller.cpp:191
Views
Definition: displayformat.h:11
void dropImage(const QString &filePath)
Controller * controller() const
Definition: imageviewer.cpp:63
virtual void mouseDragged(QPointF pt, Qt::MouseButtons buttons, size_t axis)=0
void flipH(size_t view)
flipH mirrors the current view on X axis.
Definition: controller.cpp:196
size_t depth(size_t view)
depth is the number of slices of the view.
Definition: guiimage.cpp:326
void mouseDragged(QPointF pt, Qt::MouseButtons buttons, size_t axis)
Image< D > Background(const Image< D > &img)
Segments the darker clusters of the image, supposedly belonging to the background.
void dropFolder(const QString &folderPath)
virtual void mouseReleased(QPointF pt, Qt::MouseButtons buttons, size_t axis)=0
The Controller class is one of the most important classes of the User Interface, and is responsible t...
Definition: controller.h:17
GraphicsScene * getScene(size_t axis)
bool hasViewerControls() const
void flipV(size_t view)
flipV mirrors the current view on Y axis.
Definition: controller.cpp:201
void resizeEvent(QResizeEvent *)
QPointF getIntersection(size_t view)
Definition: guiimage.cpp:168
QColor overlayColor() const
QGraphicsPixmapItem * getLabelItem(size_t view)
getLabelItem returns the LabelItem of the view.
Definition: controller.cpp:247
QGraphicsPixmapItem * getPixmapItem(size_t view)
getPixmapItem returns the PixmapItem of the view.
Definition: controller.cpp:243
GuiImage * currentImage()
currentImage
Definition: controller.cpp:24
virtual void mouseClicked(QPointF pt, Qt::MouseButtons buttons, size_t axis)=0
void currentImageChanged()
This signal is emmited every time the current image changes.
void dropImage(const QString &filePath)
bool overlay() const
Layout currentLayout() const
size_t currentSlice(size_t view)
currentSlice is the view&#39;s current slice.
Definition: guiimage.cpp:447
Views currentViews() const
QVector< Tool * > tools
tools is a vector containing the image tools.
Definition: guiimage.h:98
void setOverlay(bool overlay)
Layout
Definition: displayformat.h:10
void mouseMoved(QPointF pt, size_t axis)
void rotate(size_t viewNbr)
virtual void mouseMoved(QPointF pt, size_t axis)=0
void setController(Controller *value)
Definition: imageviewer.cpp:45
void imageUpdated()
This signal is emmited every time the current image is updated.