fw4spl
scene2D/src/scene2D/adaptor/SAxis.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2017.
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 "scene2D/adaptor/SAxis.hpp"
8 
9 #include <fwRenderQt/data/InitQtPen.hpp>
10 
11 #include <fwServices/macros.hpp>
12 
13 #include <QGraphicsItemGroup>
14 
15 fwServicesRegisterMacro( ::fwRenderQt::IAdaptor, ::scene2D::adaptor::SAxis);
16 
17 namespace scene2D
18 {
19 
20 namespace adaptor
21 {
22 
23 static const ::fwServices::IService::KeyType s_VIEWPORT_INPUT = "viewport";
24 
25 SAxis::SAxis() noexcept :
26  m_interval(1.f),
27  m_min(0.f),
28  m_max(0.f),
29  m_tickSize(1.0f),
30  m_showLine(true),
31  m_layer(nullptr),
32  m_line(nullptr),
33  m_color(Qt::white)
34 {
35 }
36 
37 //--------------------------------------------------------------------------------------------------
38 
39 SAxis::~SAxis() noexcept
40 {
41 }
42 
43 //--------------------------------------------------------------------------------------------------
44 
46 {
47  this->buildAxis();
48  this->updating();
49 }
50 
51 //--------------------------------------------------------------------------------------------------
52 
54 {
55  delete m_layer;
56 }
57 
58 //--------------------------------------------------------------------------------------------------
59 
61 {
62  this->configureParams(); // Looks for 'xAxis', 'yAxis' and 'zValue'
63 
64  const ConfigType config = this->getConfigTree().get_child("config.<xmlattr>");
65 
66  // 'color'
67  if (config.count("color"))
68  {
69  ::fwRenderQt::data::InitQtPen::setPenColor(m_color, config.get<std::string>("color"));
70  }
71 
72  // 'align' attribute configuration
73  m_align = config.get<std::string>("align");
74  SLM_ASSERT("'align' attribute is missing. Please add an 'align' attribute "
75  "with value 'left', 'right', 'top' or 'bottom'", !m_align.empty());
76  SLM_ASSERT("Unsupported value for 'align' attribute.",
77  m_align == "left" || m_align == "right" || m_align == "top" || m_align == "bottom");
78 
79  // SAxis bounds
80  SLM_ASSERT("'min' attribute is missing.", config.count("min"));
81  SLM_ASSERT("'max' attribute is missing.", config.count("max"));
82  m_min = config.get<float>("min");
83  m_max = config.get<float>("max");
84 
85  // Ticks size
86  m_tickSize = config.get<float>("tickSize", 1.0f);
87 
88  // Step
89  m_interval = config.get<float>("interval", 1.0f);
90 }
91 
92 //---------------------------------------------------------------------------------------------------------------
93 
94 void SAxis::buildAxis()
95 {
96  m_color.setCosmetic(true);
97  const int nbValues = (m_max - m_min) / m_interval + 1;
98  m_layer = new QGraphicsItemGroup();
99 
100  for(int i = 0; i < nbValues; ++i)
101  {
102  QGraphicsLineItem* tick = new QGraphicsLineItem(0, 0, 0, 0);
103  tick->setCacheMode( QGraphicsItem::DeviceCoordinateCache );
104  tick->setPen( m_color );
105 
106  m_ticks.push_back( tick );
107  m_layer->addToGroup( tick );
108  }
109 
110  m_line = new QGraphicsLineItem();
111  m_line->setCacheMode( QGraphicsItem::DeviceCoordinateCache );
112  m_line->setPen( m_color );
113 
114  if( m_showLine )
115  {
116  m_layer->addToGroup( m_line );
117  }
118 
119  // Adjust the layer's position and zValue depending on the associated axis
120  m_layer->setPos( m_xAxis->getOrigin(), m_yAxis->getOrigin() );
121  m_layer->setZValue( m_zValue );
122 
123  // Add to the scene the unique item which gather the whole set of rectangle graphic items:
124  this->getScene2DRender()->getScene()->addItem( m_layer );
125 }
126 
127 //---------------------------------------------------------------------------------------
128 
129 double SAxis::getStartVal()
130 {
131  return (int)( m_min / m_interval ) * m_interval;
132 }
133 
134 //---------------------------------------------------------------------------------------
135 
136 double SAxis::getEndVal()
137 {
138  return (int)( m_max / m_interval ) * m_interval;
139 }
140 
141 //---------------------------------------------------------------------------------------------------------------
142 
144 {
145  this->initializeViewSize();
146  this->initializeViewportSize();
147 
148  const Scene2DRatio ratio = this->getRatio();
149 
150  ::fwRenderQt::data::Viewport::sptr viewport = this->getScene2DRender()->getViewport();
151  const double viewportHeight = viewport->getHeight();
152  const double viewportWidth = viewport->getWidth();
153 
154  const double viewportSizeRatio = viewportHeight / viewportWidth;
155  const double viewInitialSizeRatio = m_viewInitialSize.first / m_viewInitialSize.second;
156 
157  const double viewportWidthRatio = this->getViewportSizeRatio().first;
158 
159  double scaleX = m_tickSize;
160  double scaleY = m_tickSize * viewportSizeRatio;
161  scaleY /= viewportWidthRatio;
162  scaleY *= viewInitialSizeRatio;
163 
164  scaleX = scaleX * ratio.first;
165  scaleY = scaleY * ratio.second;
166 
167  const size_t nbValues = m_ticks.size();
168 
169  const double min = this->getStartVal();
170  const double max = this->getEndVal();
171 
172  float pos;
173  Point2DType tickSize;
174  Point2DType tickPos;
175 
176  const Point2DType viewportSize =
177  this->mapAdaptorToScene(Point2DType(viewportWidth, viewportHeight), m_xAxis, m_yAxis);
178 
179  if(m_align == "bottom")
180  {
181  tickSize = this->mapAdaptorToScene(Point2DType(0, m_tickSize), m_xAxis, m_yAxis);
182 
183  const double tickPosY = viewport->getY();
184 
185  for(int i = 0; i < nbValues; ++i)
186  {
187  pos = min + i * m_interval;
188  tickPos = this->mapAdaptorToScene(Point2DType(pos, tickPosY), m_xAxis, m_yAxis);
189  m_ticks.at(i)->setLine(
190  tickPos.first, tickPos.second,
191  tickPos.first, tickPos.second - tickSize.second * scaleY);
192  }
193 
194  m_line->setLine(min, tickPos.second, max, tickPos.second);
195  }
196  else if(m_align == "top")
197  {
198  tickSize = this->mapAdaptorToScene(Point2DType(0, m_tickSize), m_xAxis, m_yAxis);
199 
200  const double tickPosY = viewport->getHeight() * 0.9;
201 
202  for(int i = 0; i < nbValues; ++i)
203  {
204  pos = min + i * m_interval;
205  tickPos = this->mapAdaptorToScene(Point2DType(pos, tickPosY), m_xAxis, m_yAxis);
206 
207  m_ticks.at(i)->setLine(
208  tickPos.first, tickPos.second,
209  tickPos.first, tickPos.second - tickSize.second * scaleY);
210  }
211 
212  m_line->setLine(min, tickPos.second, max, tickPos.second);
213  }
214  else if(m_align == "left")
215  {
216  tickSize = this->mapAdaptorToScene(Point2DType(m_tickSize, 0), m_xAxis, m_yAxis);
217 
218  const double tickPosX = viewport->getX();
219 
220  for(int i = 0; i < nbValues; ++i)
221  {
222  pos = min + i * m_interval;
223  tickPos = this->mapAdaptorToScene(Point2DType(tickPosX, pos), m_xAxis, m_yAxis);
224  m_ticks.at(i)->setLine(
225  tickPos.first, tickPos.second,
226  tickPos.first + tickSize.first * scaleX, tickPos.second);
227  }
228 
229  m_line->setLine( tickPos.first, min, tickPos.first, tickPos.second);
230  }
231  else if(m_align == "right")
232  {
233  tickSize = this->mapAdaptorToScene(Point2DType(m_tickSize, 0), m_xAxis, m_yAxis);
234 
235  const double tickPosX = viewport->getX() + viewport->getWidth();
236 
237  for(int i = 0; i < nbValues; ++i)
238  {
239  pos = min + i * m_interval;
240 
241  tickPos = this->mapAdaptorToScene(Point2DType(tickPosX, pos), m_xAxis, m_yAxis);
242 
243  m_ticks.at(i)->setLine(
244  tickPos.first - tickSize.first * scaleX, tickPos.second,
245  tickPos.first, tickPos.second);
246  }
247 
248  m_line->setLine(tickPos.first, min, tickPos.first, tickPos.second);
249  }
250 }
251 
252 //---------------------------------------------------------------------------------------
253 
255 {
256  if( _event.getType() == ::fwRenderQt::data::Event::Resize)
257  {
258  this->updating();
259  }
260 }
261 
262 //----------------------------------------------------------------------------------------------------------
263 
265 {
266  KeyConnectionsMap connections;
267  connections.push( s_VIEWPORT_INPUT, ::fwRenderQt::data::Viewport::s_MODIFIED_SIG, s_UPDATE_SLOT );
268  return connections;
269 }
270 
271 //--------------------------------------------------------------------------------------------------
272 
273 } // namespace adaptor
274 } // namespace scene2D
275 
Root class for all scene2d adaptors.
void updating() override
Perform some computations according to object (this service is attached to) attribute values and its ...
::fwRenderQt::data::Axis::sptr m_xAxis
The x Axis.
SCENE2D_API void processInteraction(::fwRenderQt::data::Event &_event) override
Manage the given events.
This class is a helper to define the connections of a service and its data.
Definition: IService.hpp:454
SCENE2D_API KeyConnectionsMap getAutoConnections() const override
Returns proposals to connect service slots to associated objects signals, this method is used for obj...
std::pair< float, float > Scene2DRatio
<width, height>
FWRENDERQT_API void initializeViewSize()
Initialize the source values used for computing view&#39;s size ratio.
FWRENDERQT_API Point2DType mapAdaptorToScene(const Point2DType &_xy, const ::fwRenderQt::data::Axis::sptr &_xAxis, const ::fwRenderQt::data::Axis::sptr &_yAxis) const
FWRENDERQT_API std::shared_ptr< ::fwRenderQt::SRender > getScene2DRender() const
Get the render that manages the IAdaptor.
std::pair< double, double > Point2DType
Point2D coordinate <X, Y>
static FWRENDERQT_API void setPenColor(QPen &_pen, std::string _color)
Set a pen a color.
Definition: InitQtPen.cpp:18
This bundles contains data and services used to display a 2D Qt scene.
#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
FWRENDERQT_API void initializeViewportSize()
Initialize the source values used for computing viewport&#39;s size ratio.
::fwRenderQt::data::Axis::sptr m_yAxis
The y Axis.
void stopping() override
Uninitialize the service activity. The stop() method is always invoked before destroying a service...
FWRENDERQT_API ViewportSizeRatio getViewportSizeRatio() const
Return the ratio between viewport&#39;s initial size and its current size.
FWRENDERQT_API void configureParams()
Parse the xml configuration for Axis, z value and opacity.
static FWDATA_APIconst::fwCom::Signals::SignalKeyType s_MODIFIED_SIG
Key in m_signals map of signal m_sigModified.
void configuring() override
Configure the service before starting. Apply the configuration to service.
This class manage events on the scene 2D (mouse event, keyboard event , ...).
Definition: Event.hpp:26
void starting() override
Initialize the service activity.
static FWSERVICES_APIconst::fwCom::Slots::SlotKeyType s_UPDATE_SLOT
Slot to call start method.
Definition: IService.hpp:177
FWSERVICES_API ConfigType getConfigTree() const
Return the configuration, in an boost property tree.
Definition: IService.cpp:247