BasicStrokePropertyItem.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/qt/widgets/se/BasicStrokePropertyItem.cpp
22 
23  \brief A widget used to define the basic fill se object.
24 */
25 
26 // TerraLib
27 #include "../../../raster/Utils.h"
28 #include "../../../se/Config.h"
29 #include "../../../se/Stroke.h"
30 #include "../../../se/SvgParameter.h"
31 #include "../../../se/Utils.h"
32 #include "../../../maptools/Utils.h"
33 #include "../../../maptools/Enums.h"
34 #include "../propertybrowser/AbstractPropertyManager.h"
36 
37 // Qt
38 #include <QPainter>
39 #include <QIcon>
40 
41 // QtPropertyBrowser
42 #include <QtPropertyBrowser/QtTreePropertyBrowser>
43 #include <QtPropertyBrowser/QtVariantPropertyManager>
44 
45 // STL
46 #include <cassert>
47 
48 
49 te::qt::widgets::BasicStrokePropertyItem::BasicStrokePropertyItem(QtTreePropertyBrowser* pb, QColor c) : te::qt::widgets::AbstractPropertyItem(pb, c),
50  m_stroke(new te::se::Stroke)
51 {
52  //build property browser basic stroke
53  QtProperty* basicStrokeProperty = te::qt::widgets::AbstractPropertyManager::getInstance().m_groupManager->addProperty(tr("Basic Stroke"));
54 
55  //color
56  m_colorProperty = te::qt::widgets::AbstractPropertyManager::getInstance().m_colorManager->addProperty(tr("Color"));
58  basicStrokeProperty->addSubProperty(m_colorProperty);
59 
60  //opacity
61  m_opacityProperty = te::qt::widgets::AbstractPropertyManager::getInstance().m_intSliderManager->addProperty(tr("Opacity"));
64  te::qt::widgets::AbstractPropertyManager::getInstance().m_intSliderManager->setMaximum(m_opacityProperty, 255);
65  te::qt::widgets::AbstractPropertyManager::getInstance().m_intSliderManager->setSingleStep(m_opacityProperty, 10);
66  basicStrokeProperty->addSubProperty(m_opacityProperty);
67 
68  //width
69  m_widthProperty = te::qt::widgets::AbstractPropertyManager::getInstance().m_doubleManager->addProperty(tr("Width"));
75  basicStrokeProperty->addSubProperty(m_widthProperty);
76 
77  //dash
78  m_dashProperty = te::qt::widgets::AbstractPropertyManager::getInstance().m_enumManager->addProperty(tr("Dash"));
81  basicStrokeProperty->addSubProperty(m_dashProperty);
82 
83  //join
84  m_joinProperty = te::qt::widgets::AbstractPropertyManager::getInstance().m_enumManager->addProperty(tr("Join"));
87  basicStrokeProperty->addSubProperty(m_joinProperty);
88 
89  //cap
90  m_capProperty = te::qt::widgets::AbstractPropertyManager::getInstance().m_enumManager->addProperty(tr("Cap"));
93  basicStrokeProperty->addSubProperty(m_capProperty);
94 
95  addProperty(basicStrokeProperty, tr("Basic Stroke"), QColor(175, 255, 175));
96 
97  m_update = true;
98 }
99 
101 {
102  delete m_stroke;
103 }
104 
106 {
107  assert(stroke);
108 
109  delete m_stroke;
110 
111  m_stroke = stroke->clone();
112 
113  updateUi();
114 }
115 
117 {
118  return m_stroke->clone();
119 }
120 
122 {
123  // Color
125  te::se::GetColor(m_stroke, rgba);
126  QColor c = QColor(rgba.getRgba());
127 
128  int alpha = 255;
129 
130  if (m_stroke->getOpacity())
132 
133  c.setAlpha(alpha);
134 
136 
137  // Opacity
138  te::qt::widgets::AbstractPropertyManager::getInstance().m_intSliderManager->setValue(m_opacityProperty, alpha);
139 
140  // Width
141  const te::se::SvgParameter* width = m_stroke->getWidth();
142  if(width)
144 
145  // Dash style
146  const te::se::SvgParameter* dasharray = m_stroke->getDashArray();
147  if(dasharray)
148  {
149  std::string str = te::se::GetString(dasharray);
150  for(size_t t = 0; t < m_dashes.size(); ++t)
151  {
152  if(str == m_dashes[t])
153  {
154  te::qt::widgets::AbstractPropertyManager::getInstance().m_enumManager->setValue(m_dashProperty, static_cast<int>(t));
155  break;
156  }
157  }
158  }
159  else
160  {
162  }
163 
164  // Join Style
165  const te::se::SvgParameter* join = m_stroke->getLineJoin();
166  if(join)
167  {
168  std::string joinStr = te::se::GetString(join);
169 
170  std::map<int, std::string>::iterator it = m_joinMap.begin();
171 
172  while(it != m_joinMap.end())
173  {
174  if(it->second == joinStr)
175  {
176  te::qt::widgets::AbstractPropertyManager::getInstance().m_enumManager->setValue(m_joinProperty, it->first);
177  }
178 
179  ++it;
180  }
181  }
182  else
183  {
184  te::qt::widgets::AbstractPropertyManager::getInstance().m_enumManager->setValue(m_joinProperty, 0); //TE_SE_MITRE_JOIN
185  }
186 
187  // Cap Style
188  const te::se::SvgParameter* cap = m_stroke->getLineCap();
189  if(cap)
190  {
191  std::string capStr = te::se::GetString(cap);
192 
193  std::map<int, std::string>::iterator it = m_capMap.begin();
194 
195  while(it != m_capMap.end())
196  {
197  if(it->second == capStr)
198  {
199  te::qt::widgets::AbstractPropertyManager::getInstance().m_enumManager->setValue(m_capProperty, it->first);
200  }
201 
202  ++it;
203  }
204  }
205  else
206  {
207  te::qt::widgets::AbstractPropertyManager::getInstance().m_enumManager->setValue(m_capProperty, 0); //TE_SE_BUTT_CAP
208  }
209 }
210 
212 {
213  if(!m_update)
214  return;
215 
216  if(p == m_opacityProperty)
217  {
218  m_update = false;
219 
220  m_color.setAlpha(value);
221 
222  double opacity = value / 255.;
223 
224  // Updating stroke opacity
225  m_stroke->setOpacity(QString::number(opacity, 'g', 2).toUtf8().data());
226 
227  updateUi();
228 
229  emit strokeChanged();
230 
231  m_update = true;
232  }
233  else if(p == m_dashProperty)
234  {
235  if(value == -1)
236  return;
237 
238  m_update = false;
239 
240  std::string pattern = m_dashes[value];
241  m_stroke->setDashArray(pattern);
242 
243  updateUi();
244 
245  emit strokeChanged();
246 
247  m_update = true;
248  }
249  else if(p == m_joinProperty)
250  {
251  m_update = false;
252 
253  m_stroke->setLineJoin(m_joinMap[value]);
254 
255  updateUi();
256 
257  emit strokeChanged();
258 
259  m_update = true;
260  }
261  else if(p == m_capProperty)
262  {
263  m_update = false;
264 
265  m_stroke->setLineCap(m_capMap[value]);
266 
267  updateUi();
268 
269  emit strokeChanged();
270 
271  m_update = true;
272  }
273 }
274 
276 {
277  if(!m_update)
278  return;
279 
280  m_update = false;
281 
282  if(p == m_widthProperty)
283  {
284  QString str;
285  str.setNum(value);
286 
287  m_stroke->setWidth(str.toUtf8().data());
288  emit strokeChanged();
289  }
290 
291  m_update = true;
292 }
293 
294 void te::qt::widgets::BasicStrokePropertyItem::valueChanged(QtProperty *p, const QColor &value)
295 {
296  if(!m_update)
297  return;
298 
299  m_update = false;
300 
301  if(p == m_colorProperty)
302  {
303  // The new stroke color
304  m_color.setRgb(value.red(), value.green(), value.blue(), value.alpha());
305 
306  double alpha = value.alpha() / 255.;
307 
308  // Updating stroke color
309  m_stroke->setColor(m_color.name().toUtf8().data());
310  m_stroke->setOpacity(QString::number(alpha, 'g', 2).toUtf8().data());
311 
312  updateUi();
313 
314  emit strokeChanged();
315  }
316 
317  m_update = true;
318 }
319 
321 {
322  QMap<int, QIcon> map;
323 
324  // Dash graphical representation size
325  QSize size(32, 16);
326 
327  // Line that will be draw with the dashe styles
328  QLine line(0, size.height() * 0.5, size.width(), size.height() * 0.5);
329 
330  // Setuping...
331  QPen pen;
332  pen.setWidth(2);
333 
334  int dSize = static_cast<int>(m_dashes.size());
335 
336  for(int t = 0; t < dSize; ++t)
337  {
338  QPixmap pixmap(size);
339  pixmap.fill(Qt::transparent);
340 
341  QPainter painter(&pixmap);
342 
343  std::string pattern = m_dashes[t];
344  std::vector<double> dasharray;
345  te::map::GetDashStyle(pattern, dasharray);
346 
347  QVector<qreal> qdasharray = QVector<qreal>::fromStdVector(dasharray);
348 
349  pen.setDashPattern(qdasharray);
350  painter.setPen(pen);
351  painter.drawLine(line);
352 
353  QIcon icon(pixmap);
354 
355  map[t] = icon;
356  }
357 
358  return map;
359 }
360 
362 {
363  QMap<int, QIcon> map;
364 
365  map[0] = QIcon::fromTheme("stroke-join-miter").pixmap(16,16);
366  map[1] = QIcon::fromTheme("stroke-join-round").pixmap(16,16);
367  map[2] = QIcon::fromTheme("stroke-join-bevel").pixmap(16,16);
368 
369  return map;
370 }
371 
373 {
374  QMap<int, QIcon> map;
375 
376  map[0] = QIcon::fromTheme("stroke-cap-butt").pixmap(16,16);
377  map[1] = QIcon::fromTheme("stroke-cap-round").pixmap(16,16);
378  map[2] = QIcon::fromTheme("stroke-cap-square").pixmap(16,16);
379 
380  return map;
381 }
382 
384 {
385  m_dashes.push_back("");
386  m_dashes.push_back("1 2");
387  m_dashes.push_back("4 2");
388  m_dashes.push_back("4 2 1 2");
389  m_dashes.push_back("4 2 1 2 1 2");
390 
391  QStringList l;
392 
393  for(size_t t = 0; t < m_dashes.size(); ++t)
394  {
395  l << m_dashes[t].c_str();
396  }
397 
398  return l;
399 }
400 
402 {
403  m_joinMap.insert(std::map<int, std::string>::value_type(0, TE_SE_MITRE_JOIN));
404  m_joinMap.insert(std::map<int, std::string>::value_type(1, TE_SE_ROUND_JOIN));
405  m_joinMap.insert(std::map<int, std::string>::value_type(2, TE_SE_BEVEL_JOIN));
406 
407  QStringList l;
408 
409  l << m_joinMap[0].c_str();
410  l << m_joinMap[1].c_str();
411  l << m_joinMap[2].c_str();
412 
413  return l;
414 }
415 
417 {
418  m_capMap.insert(std::map<int, std::string>::value_type(0, TE_SE_BUTT_CAP));
419  m_capMap.insert(std::map<int, std::string>::value_type(1, TE_SE_ROUND_CAP));
420  m_capMap.insert(std::map<int, std::string>::value_type(2, TE_SE_SQUARE_CAP));
421 
422  QStringList l;
423 
424  l << m_capMap[0].c_str();
425  l << m_capMap[1].c_str();
426  l << m_capMap[2].c_str();
427 
428  return l;
429 }
Stroke * clone() const
It creates a new copy of this object.
Definition: Stroke.cpp:158
void getRgba(int *r, int *g, int *b, int *a=0) const
It gets the color value.
Definition: RGBAColor.h:327
const SvgParameter * getLineCap() const
Definition: Stroke.cpp:143
TESEEXPORT void GetColor(const te::se::Stroke *stroke, te::color::RGBAColor &color)
It gets the RGBA color from the Stroke element.
A widget used to define the main property items that can be used to describe a se object...
void setWidth(const std::string &width)
Definition: Stroke.cpp:98
const SvgParameter * getLineJoin() const
Definition: Stroke.cpp:138
#define TE_OPAQUE
For an RGBA color this is the value of the alpha-channel for totally opaque.
QColor m_color
Auxiliary color attribute.
te::se::Stroke * m_stroke
Stroke element that will be configured by this widget.
TESEEXPORT double GetDouble(const te::se::ParameterValue *param)
It gets the parameter value as a double.
void setDashArray(const std::string &dasharray)
Definition: Stroke.cpp:113
BasicStrokePropertyItem(QtTreePropertyBrowser *pb, QColor c=QColor())
Constructor.
void setColor(const std::string &color)
Definition: Stroke.cpp:88
void updateUi()
Updates the widget form based on internal stroke element.
unsigned int line
#define TE_SE_BEVEL_JOIN
It specifies the value "bevel" for stroke-linejoin parameter.
void setOpacity(const std::string &opacity)
Definition: Stroke.cpp:93
const SvgParameter * getOpacity() const
Definition: Stroke.cpp:128
TEMAPEXPORT void GetDashStyle(const std::string &dasharray, std::vector< double > &style)
Converts a dasharray pattern coded by a string to a vector of double.
static AbstractPropertyManager & getInstance()
It returns a reference to the singleton instance.
A widget used to define the basic fill se object.
URI C++ Library.
Definition: Attributes.h:37
#define TE_SE_BUTT_CAP
It specifies the value "butt" for stroke-linecap parameter.
TERASTEREXPORT int Round(double val)
Round a double value to a integer value.
te::se::Stroke * getStroke() const
Gets the configured stroke element.
void setLineCap(const std::string &cap)
Definition: Stroke.cpp:108
te::gm::Polygon * p
void addProperty(QtProperty *property, const QString &id, QColor c)
virtual void valueChanged(QtProperty *p, int value)
#define TE_SE_SQUARE_CAP
It specifies the value "square" for stroke-linecap parameter.
#define TE_SE_ROUND_JOIN
It specifies the value "round" for stroke-linejoin parameter.
#define TE_SE_ROUND_CAP
It specifies the value "round" for stroke-linecap parameter.
void setLineJoin(const std::string &join)
Definition: Stroke.cpp:103
const SvgParameter * getDashArray() const
Definition: Stroke.cpp:148
A Stroke specifies the appearance of a linear geometry.
Definition: Stroke.h:67
#define TE_SE_MITRE_JOIN
It specifies the value "mitre" for stroke-linejoin parameter.
A helper class for 32-bit RGBA (Red-Green-Blue-Alpha channel) color.
Definition: RGBAColor.h:57
#define TE_SE_DEFAULT_FILL_BASIC_COLOR
It specifies the default color used by basic fill (solid colors).
#define TE_SE_DEFAULT_STROKE_BASIC_COLOR
It specifies the default color used by stroke basic (solid colors).
A SvgParameter refers to an SVG/CSS graphical-formatting parameter.
Definition: SvgParameter.h:48
std::vector< std::string > m_dashes
Predefined dash styles. TODO: it can be filled out, based on a file, etc (?)
void setStroke(const te::se::Stroke *stroke)
Sets a stroke element to this widget.
TESEEXPORT std::string GetString(const te::se::ParameterValue *param)
It gets the parameter value as a string.
const SvgParameter * getWidth() const
Definition: Stroke.cpp:133