fw4spl
SrcLib/visu/fwRenderQt/src/fwRenderQt/SRender.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwRenderQt/SRender.hpp"
8 
9 #include "fwRenderQt/IAdaptor.hpp"
10 #include "fwRenderQt/registry/Adaptor.hpp"
11 #include "fwRenderQt/Scene2DGraphicsView.hpp"
12 
13 #include <fwCom/helper/SigSlotConnection.hpp>
14 #include <fwCom/Slot.hpp>
15 #include <fwCom/Slot.hxx>
16 #include <fwCom/Slots.hpp>
17 #include <fwCom/Slots.hxx>
18 
19 #include <fwDataTools/Color.hpp>
20 
21 #include <fwGuiQt/container/QtContainer.hpp>
22 
23 #include <fwServices/helper/Config.hpp>
24 #include <fwServices/macros.hpp>
25 #include <fwServices/op/Add.hpp>
26 
27 #include <QGraphicsRectItem>
28 #include <QVBoxLayout>
29 
30 namespace fwRenderQt
31 {
32 
33 SRender::SRender() noexcept :
34  m_sceneStart(-100., -100.),
35  m_sceneWidth(200., 200.),
36  m_scene(nullptr),
37  m_view(nullptr),
38  m_antialiasing(false),
39  m_background("#000000"),
40  m_aspectRatioMode(Qt::IgnoreAspectRatio)
41 {
42 }
43 
44 //-----------------------------------------------------------------------------
45 
47 {
48 }
49 
50 //-----------------------------------------------------------------------------
51 
52 QGraphicsScene* SRender::getScene() const
53 {
54  return m_scene;
55 }
56 
57 //-----------------------------------------------------------------------------
58 
60 {
61  return m_view;
62 }
63 
64 //-----------------------------------------------------------------------------
65 
66 ::fwRenderQt::data::Viewport::sptr SRender::getViewport() const
67 {
68  return m_viewport;
69 }
70 
71 //-----------------------------------------------------------------------------
72 
73 ::fwRenderQt::data::Axis::sptr SRender::getAxis(const std::string& id) const
74 {
75  ::fwRenderQt::data::Axis::sptr axis;
76  const auto iter = m_axisMap.find(id);
77  if(iter != m_axisMap.end())
78  {
79  axis = iter->second;
80  }
81  return axis;
82 }
83 
84 //-----------------------------------------------------------------------------
85 
87 {
88  /* std::map are sorted regarding to key values. Keys of m_zValue2AdaptorID are z-values (float).
89  *
90  * The dispatching is performed to the highest z-valued adaptors first, so we start iterating
91  * from the end of m_zValue2AdaptorID (with reverse_iterator).
92  */
93  if ( !_event.isAccepted() )
94  {
95  const auto& registry = ::fwRenderQt::registry::getAdaptorRegistry();
96  for( const auto& elt : registry)
97  {
98  if(elt.second == this->getID())
99  {
100  ::fwRenderQt::IAdaptor::sptr adaptor =
101  ::fwRenderQt::IAdaptor::dynamicCast(::fwTools::fwID::getObject(elt.first));
102  if(adaptor != nullptr && adaptor->isStarted())
103  {
104  adaptor->processInteraction( _event );
105  }
106  }
107  }
108  }
109 }
110 
111 //-----------------------------------------------------------------------------
112 
113 ::fwRenderQt::data::Coord SRender::mapToScene( const ::fwRenderQt::data::Coord& coord ) const
114 {
116  const QPoint qp( static_cast<int>(coord.getX()), static_cast<int>(coord.getY()) );
117  const QPointF qps = m_view->mapToScene(qp);
118  return ::fwRenderQt::data::Coord(qps.x(), qps.y());
119 }
120 
121 //-----------------------------------------------------------------------------
122 
124 {
125  this->initialize();
126 
127  std::vector < SPTR(::fwRuntime::ConfigurationElement) > vectConfig = m_configuration->find("scene");
128  SLM_ASSERT("There is no implementation between \"scene\" tags", !vectConfig.empty());
129  m_sceneConfiguration = vectConfig.at(0);
130 
132  for (iter = m_sceneConfiguration->begin(); iter != m_sceneConfiguration->end(); ++iter)
133  {
134  if ((*iter)->getName() == "axis")
135  {
136  this->configureAxis(*iter);
137  }
138  else if ((*iter)->getName() == "viewport")
139  {
140  this->configureViewport(*iter);
141  }
142  else if ((*iter)->getName() == "scene")
143  {
144  this->configureScene(*iter);
145  }
146  else if ((*iter)->getName() == "adaptor")
147  {
148  this->configureAdaptor(*iter);
149  }
150  else
151  {
152  SLM_ASSERT("Bad scene configurationType, unknown xml node : " + (*iter)->getName(), false);
153  }
154  }
155 }
156 
157 //-----------------------------------------------------------------------------
158 
160 {
161  this->create();
162 
163  this->startContext();
164 }
165 
166 //-----------------------------------------------------------------------------
167 
169 {
170 }
171 
172 //-----------------------------------------------------------------------------
173 
175 {
176 }
177 
178 //-----------------------------------------------------------------------------
179 
180 void SRender::swapping(const IService::KeyType& key)
181 {
182 }
183 
184 //-----------------------------------------------------------------------------
185 
187 {
188  m_axisMap.clear();
189 
190  this->stopContext();
191  this->destroy();
192 }
193 
194 //-----------------------------------------------------------------------------
195 
196 void SRender::startContext()
197 {
199  = ::fwGuiQt::container::QtContainer::dynamicCast(this->getContainer());
200 
201  // Convert the background color
202  std::uint8_t color[4];
203  ::fwDataTools::Color::hexaStringToRGBA(m_background, color);
204 
205  m_scene = new QGraphicsScene( m_sceneStart.getX(), m_sceneStart.getY(), m_sceneWidth.getX(), m_sceneWidth.getY());
206  m_scene->setBackgroundBrush(QBrush(QColor(color[0], color[1], color[2], color[3])));
207  m_scene->setFocus( Qt::MouseFocusReason );
208 
209  m_view = new Scene2DGraphicsView( m_scene, qtContainer->getQtContainer() );
210  m_view->setViewport( m_viewport );
211  m_view->setSceneRender( ::fwRenderQt::SRender::dynamicCast( this->getSptr() ) );
212  m_view->setRenderHint( QPainter::Antialiasing, m_antialiasing );
213 
214  QVBoxLayout* layout = new QVBoxLayout;
215  layout->addWidget(m_view);
216  qtContainer->setLayout(layout);
217 
218  m_view->updateFromViewport();
219 }
220 
221 //-----------------------------------------------------------------------------
222 
223 void SRender::stopContext()
224 {
225  delete m_scene;
226  delete m_view;
227 }
228 
229 //-----------------------------------------------------------------------------
230 
231 Qt::AspectRatioMode SRender::getAspectRatioMode() const
232 {
233  return m_aspectRatioMode;
234 }
235 
236 //-----------------------------------------------------------------------------
237 
238 void SRender::configureAxis( ConfigurationType _conf )
239 {
240  SLM_ASSERT("\"axis\" tag required", _conf->getName() == "axis");
241 
242  const std::string id = _conf->getAttributeValue("id");
243  const std::string origin = _conf->getAttributeValue("origin");
244  const std::string scale = _conf->getAttributeValue("scale");
245  const std::string scaleType = _conf->getAttributeValue("scaleType");
246 
247  ::fwRenderQt::data::Axis::sptr axis = std::make_shared< ::fwRenderQt::data::Axis >();
248  axis->setOrigin(std::stof( origin ));
249  axis->setScale(std::stof( scale ));
250  axis->setScaleType( scaleType == "LINEAR" ? ::fwRenderQt::data::Axis::LINEAR : ::fwRenderQt::data::Axis::LOG);
251  m_axisMap[id] = axis;
252 }
253 
254 //-----------------------------------------------------------------------------
255 
256 void SRender::configureViewport( ConfigurationType _conf )
257 {
258  SLM_ASSERT("\"viewport\" tag required", _conf->getName() == "viewport");
259 
260  const std::string id = _conf->getAttributeValue("id");
261  const std::string x = _conf->getAttributeValue("x");
262  const std::string y = _conf->getAttributeValue("y");
263  const std::string width = _conf->getAttributeValue("width");
264  const std::string height = _conf->getAttributeValue("height");
265 
266  m_viewport = ::fwRenderQt::data::Viewport::New();
267  m_viewport->setX(std::stof( x ));
268  m_viewport->setY(std::stof( y ));
269  m_viewport->setWidth(std::stof( width ));
270  m_viewport->setHeight(std::stof( height ));
271 }
272 
273 //-----------------------------------------------------------------------------
274 
275 void SRender::configureScene( ConfigurationType _conf )
276 {
277  SLM_ASSERT("\"scene\" tag required", _conf->getName() == "scene");
278 
279  const std::string x = _conf->getAttributeValue("x");
280  const std::string y = _conf->getAttributeValue("y");
281  const std::string width = _conf->getAttributeValue("width");
282  const std::string height = _conf->getAttributeValue("height");
283 
284  m_sceneStart.setX( std::stof( x ) );
285  m_sceneStart.setY( std::stof( y ) );
286  m_sceneWidth.setX( std::stof( width ) );
287  m_sceneWidth.setY( std::stof( height ) );
288 
289  if( _conf->hasAttribute("antialiasing"))
290  {
291  if( _conf->getAttributeValue("antialiasing") == "true")
292  {
293  m_antialiasing = true;
294  }
295  }
296 
297  if( _conf->hasAttribute("aspectRatioMode"))
298  {
299  const std::string aspectRatio = _conf->getAttributeValue("aspectRatioMode");
300  if(aspectRatio == "KeepAspectRatioByExpanding")
301  {
302  m_aspectRatioMode = Qt::KeepAspectRatioByExpanding;
303  }
304  else if(aspectRatio == "KeepAspectRatio")
305  {
306  m_aspectRatioMode = Qt::KeepAspectRatio;
307  }
308  else
309  {
310  OSLM_ERROR_IF("Unknown aspect ratio (" <<
311  aspectRatio <<
312  "). Possible values are: KeepAspectRatio, KeepAspectRatioByExpanding or IgnoreAspectRatio.",
313  aspectRatio != "IgnoreAspectRatio");
314  m_aspectRatioMode = Qt::IgnoreAspectRatio;
315  }
316  }
317 
318  if ( _conf->hasAttribute(("background")) )
319  {
320  m_background = _conf->getAttributeValue("background");
321  SLM_ASSERT("Color format must be hexadecimal.", m_background[0] == '#');
322  }
323 }
324 
325 //-----------------------------------------------------------------------------
326 
327 void SRender::configureAdaptor( ConfigurationType _conf )
328 {
329  SLM_ASSERT("\"adaptor\" tag required", _conf->getName() == "adaptor");
330 
331  const std::string adaptorId = _conf->getAttributeValue("uid");
332 
333  auto& registry = ::fwRenderQt::registry::getAdaptorRegistry();
334  registry[adaptorId] = this->getID();
335 }
336 
337 //-----------------------------------------------------------------------------
338 
339 void SRender::updateSceneSize( float ratioPercent )
340 {
341  QRectF rec = m_scene->itemsBoundingRect();
342  qreal x, y, w, h;
343  rec.getRect(&x, &y, &w, &h);
344 
345  if ( ratioPercent != 0 )
346  {
347  qreal centerX = x + w/2.0;
348  qreal centerY = y + h/2.0;
349  w = w + w * ratioPercent;
350  h = h + h * ratioPercent;
351  x = centerX - w/2.0;
352  y = centerY - h/2.0;
353  rec.setRect(x, y, w, h);
354  }
355  m_sceneStart.setX( x );
356  m_sceneStart.setY( y );
357  m_sceneWidth.setX( w );
358  m_sceneWidth.setY( h );
359 
360  m_scene->setSceneRect( rec );
361 }
362 
363 //-----------------------------------------------------------------------------
364 
365 } // namespace fwRenderQt
#define SPTR(_cls_)
static FWDATATOOLS_API void hexaStringToRGBA(const std::string &_hexaColor, std::uint8_t _rgba[4])
Convert a color coded as an hexadecimal string into an array of four bytes (RGBA) ...
Contains fwAtomsFilter::registry details.
FWRENDERQT_API void swapping() override
Swap the service from associated object to another object.
FWGUI_API void destroy()
Stops sub-views and toobar services. Destroys view, sub-views and toolbar containers.
FWRENDERQT_API void updateSceneSize(float ratioPercent=0)
Update scene size from items bounding rect, this bounding can be enlarged with ratioPercent parameter...
FWRENDERQT_API::fwRenderQt::data::Coord mapToScene(const ::fwRenderQt::data::Coord &coord) const
Returns the viewport coordinate point mapped to scene coordinates.
virtual FWRENDERQT_API ~SRender() noexcept
Basic destructor, do nothing.
FWRENDERQT_API::fwRenderQt::data::Viewport::sptr getViewport() const
Get the viewport.
FWRENDERQT_API Qt::AspectRatioMode getAspectRatioMode() const
Returns what happens to scene&#39;s aspect ratio on view resize events.
FWRENDERQT_API QGraphicsScene * getScene() const
Get the scene.
FWTOOLS_API IDType getID(Policy policy=GENERATE) const
Returns the id of the object. If it is not set and the policy value is.
Definition: fwID.cpp:78
FWRENDERQT_API::fwRenderQt::data::Axis::sptr getAxis(const std::string &id) const
Get the axis.
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
::fwRuntime::ConfigurationElement::sptr m_configuration
Configuration element used to configure service internal state using a generic XML like structure TOD...
Definition: IService.hpp:670
FWGUI_API void create()
Creates view, sub-views and toolbar containers. Manages sub-views and toobar services.
FWRENDERQT_API void configuring() override
Get configuration options from XML.
FWRENDERQT_API void updating() override
Do nothing.
The namespace fwRenderQt contains classes for rendering with Qt.
Definition: Axis.hpp:12
Container::iterator Iterator
Defines the configuration element container type.
FWRENDERQT_API void dispatchInteraction(::fwRenderQt::data::Event &_event)
FWRENDERQT_API Scene2DGraphicsView * getView() const
Get the view.
This class manage events on the scene 2D (mouse event, keyboard event , ...).
Definition: Event.hpp:26
#define OSLM_ERROR_IF(message, cond)
Definition: spyLog.hpp:278
Defines the QWidget container for UI.
Definition: QtContainer.hpp:35
FWGUI_API void initialize()
Initialize managers.
static FWTOOLS_API std::shared_ptr< ::fwTools::Object > getObject(IDType requestID)
Retrieve the object attached to the given id. Return a null sptr if no correspondence exist...
Definition: fwID.cpp:117