string_display.cpp
Go to the documentation of this file.
1 // -*- mode: c++; -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2019, JSK Lab
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/o2r other materials provided
17  * with the distribution.
18  * * Neither the name of the JSK Lab nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
36 #include "string_display.h"
37 
38 #include <string>
39 
40 #include <boost/algorithm/string.hpp>
41 #include <boost/format.hpp>
43 #include <OGRE/OgreHardwarePixelBuffer.h>
44 #include <OGRE/OgreMaterialManager.h>
45 #include <OGRE/OgreTexture.h>
47 #include <QFontDatabase>
48 #include <QPainter>
49 #include <QStaticText>
50 #include <QTextDocument>
52 
53 namespace jsk_rviz_plugins
54 {
56  texture_width_(0), texture_height_(0),
57  text_size_(14),
58  line_width_(2),
59  text_(""), font_(""),
60  bg_color_(0, 0, 0, 0),
61  fg_color_(255, 255, 255, 255.0),
62  require_update_texture_(false)
63  {
65  "Topic", "",
66  ros::message_traits::datatype<std_msgs::String>(),
67  "std_msgs::String topic to subscribe to.",
68  this, SLOT(updateTopic()));
70  "Overtake Position Properties", false,
71  "overtake position properties specified by message such as left, top and font",
72  this, SLOT(updateOvertakePositionProperties()));
74  "Overtake Color Properties", false,
75  "overtake color properties specified by message such as foreground/background color and alpha",
76  this, SLOT(updateOvertakeColorProperties()));
78  "Align Bottom", false,
79  "align text with the bottom of the overlay region",
80  this, SLOT(updateAlignBottom()));
82  "top", 0,
83  "top position",
84  this, SLOT(updateTop()));
87  "left", 0,
88  "left position",
89  this, SLOT(updateLeft()));
92  "width", 128,
93  "width position",
94  this, SLOT(updateWidth()));
97  "height", 128,
98  "height position",
99  this, SLOT(updateHeight()));
102  "text size", 12,
103  "text size",
104  this, SLOT(updateTextSize()));
107  "line width", 2,
108  "line width",
109  this, SLOT(updateLineWidth()));
112  "Foreground Color", QColor(25, 255, 240),
113  "Foreground Color",
114  this, SLOT(updateFGColor()));
116  "Foreground Alpha", 0.8, "Foreground Alpha",
117  this, SLOT(updateFGAlpha()));
121  "Background Color", QColor(0, 0, 0),
122  "Background Color",
123  this, SLOT(updateBGColor()));
125  "Background Alpha", 0.8, "Background Alpha",
126  this, SLOT(updateBGAlpha()));
129 
130  QFontDatabase database;
131  font_families_ = database.families();
133  "font", "DejaVu Sans Mono",
134  "font", this,
135  SLOT(updateFont()));
136  for (size_t i = 0; i < font_families_.size(); i++)
137  {
138  font_property_->addOption(font_families_[i], static_cast<int>(i));
139  }
140  }
141 
143  {
144  onDisable();
145  //delete overlay_;
146  delete update_topic_property_;
149  delete align_bottom_property_;
150  delete top_property_;
151  delete left_property_;
152  delete width_property_;
153  delete height_property_;
154  delete text_size_property_;
155  delete line_width_property_;
156  delete bg_color_property_;
157  delete bg_alpha_property_;
158  delete fg_color_property_;
159  delete fg_alpha_property_;
160  delete font_property_;
161  }
162 
164  {
165  if (overlay_)
166  {
167  overlay_->show();
168  }
169  subscribe();
170  }
171 
173  {
174  if (overlay_)
175  {
176  overlay_->hide();
177  }
178  unsubscribe();
179  }
180 
182  {
183  sub_.shutdown();
184  }
185 
187  {
188  std::string topic_name = update_topic_property_->getTopicStd();
189  if (topic_name.length() > 0 && topic_name != "/")
190  {
191  sub_ = ros::NodeHandle().subscribe(topic_name, 1, &StringDisplay::processMessage, this);
192  }
193  }
194 
196  {
197  unsubscribe();
198  subscribe();
199  }
200 
201  // only the first time
203  {
204  onEnable();
205  updateTopic();
209  updateTop();
210  updateLeft();
211  updateWidth();
212  updateHeight();
213  updateTextSize();
214  updateFGColor();
215  updateFGAlpha();
216  updateBGColor();
217  updateBGAlpha();
218  updateFont();
219  updateLineWidth();
221  }
222 
223  void StringDisplay::update(float wall_dt, float ros_dt)
224  {
226  {
227  return;
228  }
229  if (!isEnabled())
230  {
231  return;
232  }
233  if (!overlay_)
234  {
235  return;
236  }
237  overlay_->setPosition(left_, top_);
238  overlay_->updateTextureSize(texture_width_, texture_height_);
239  {
240  ScopedPixelBuffer buffer = overlay_->getBuffer();
241  QImage Hud = buffer.getQImage(*overlay_, bg_color_);
242  QPainter painter( &Hud );
243  painter.setRenderHint(QPainter::Antialiasing, true);
244  painter.setPen(QPen(fg_color_, line_width_ || 1, Qt::SolidLine));
245  uint16_t w = overlay_->getTextureWidth();
246  uint16_t h = overlay_->getTextureHeight();
247 
248  // font
249  if (text_size_ != 0)
250  {
251  QFont font(font_.length() > 0 ? font_.c_str(): "Liberation Sans");
252  font.setPointSize(text_size_);
253  font.setBold(true);
254  painter.setFont(font);
255  }
256  if (text_.length() > 0)
257  {
258  std::string color_wrapped_text
259  = (boost::format("<span style=\"color: rgba(%2%, %3%, %4%, %5%)\">%1%</span>")
260  % text_ % fg_color_.red() % fg_color_.green() % fg_color_.blue() %
261  fg_color_.alpha()).str();
262  QStaticText static_text(
263  boost::algorithm::replace_all_copy(color_wrapped_text, "\n", "<br >").c_str());
264  static_text.setTextWidth(w);
265  if (!align_bottom_)
266  {
267  painter.drawStaticText(0, 0, static_text);
268  }
269  else
270  {
271  QStaticText only_wrapped_text(color_wrapped_text.c_str());
272  QFontMetrics fm(painter.fontMetrics());
273  QRect text_rect = fm.boundingRect(0, 0, w, h,
274  Qt::TextWordWrap | Qt::AlignLeft | Qt::AlignTop,
275  only_wrapped_text.text().remove(QRegExp("<[^>]*>")));
276  painter.drawStaticText(0, h - text_rect.height(), static_text);
277  }
278  }
279  painter.end();
280  }
281  overlay_->setDimensions(overlay_->getTextureWidth(), overlay_->getTextureHeight());
282  require_update_texture_ = false;
283  }
284 
286  (const std_msgs::String::ConstPtr& msg)
287  {
288  if (!isEnabled())
289  {
290  return;
291  }
292  if (!overlay_)
293  {
294  static int count = 0;
296  ss << "StringDisplayObject" << count++;
297  overlay_.reset(new OverlayObject(ss.str()));
298  overlay_->show();
299  }
300  if (overlay_)
301  {
302  overlay_->show();
303  }
304 
305  // store message for update method
306  text_ = msg->data;
308  }
309 
311  {
314  {
315  updateTop();
316  updateLeft();
317  updateWidth();
318  updateHeight();
319  updateTextSize();
321  }
325  {
326  top_property_->show();
327  left_property_->show();
331  }
332  else
333  {
334  top_property_->hide();
335  left_property_->hide();
339  }
340  }
341 
343  {
346  {
347  // read all the parameters from properties
348  updateFGColor();
349  updateFGAlpha();
350  updateBGColor();
351  updateBGAlpha();
352  updateFont();
353  updateLineWidth();
355  }
358  {
364  font_property_->show();
365  }
366  else
367  {
373  font_property_->hide();
374  }
375  }
376 
378  {
380  {
382  }
384  }
385 
387  {
390  {
392  }
393  }
394 
396  {
399  {
401  }
402  }
403 
405  {
408  {
410  }
411  }
412 
414  {
417  {
419  }
420  }
421 
423  {
426  {
428  }
429  }
430 
432  {
433  QColor c = bg_color_property_->getColor();
434  bg_color_.setRed(c.red());
435  bg_color_.setGreen(c.green());
436  bg_color_.setBlue(c.blue());
438  {
440  }
441  }
442 
444  {
445  bg_color_.setAlpha(bg_alpha_property_->getFloat() * 255.0);
447  {
449  }
450  }
451 
453  {
454  QColor c = fg_color_property_->getColor();
455  fg_color_.setRed(c.red());
456  fg_color_.setGreen(c.green());
457  fg_color_.setBlue(c.blue());
459  {
461  }
462  }
463 
465  {
466  fg_color_.setAlpha(fg_alpha_property_->getFloat() * 255.0);
468  {
470  }
471  }
472 
474  {
475  int font_index = font_property_->getOptionInt();
476  if (font_index < font_families_.size())
477  {
478  font_ = font_families_[font_index].toStdString();
479  }
480  else
481  {
482  ROS_FATAL("Unexpected error at selecting font index %d.", font_index);
483  return;
484  }
486  {
488  }
489  }
490 
492  {
495  {
497  }
498  }
499 
501  {
502  return (top_ < y && top_ + texture_height_ > y &&
503  left_ < x && left_ + texture_width_ > x);
504  }
505 
507  {
508  top_ = y;
509  left_ = x;
510  }
511 
513  {
516  }
517 
518 } // namespace jsk_rviz_plugins
519 
virtual QColor getColor() const
void setMin(float min)
virtual bool setValue(const QVariant &new_value)
#define ROS_FATAL(...)
void setMax(float max)
rviz::EnumProperty * font_property_
rviz::IntProperty * top_property_
rviz::IntProperty * left_property_
virtual QImage getQImage(unsigned int width, unsigned int height)
PLUGINLIB_EXPORT_CLASS(jsk_rviz_plugins::PictogramArrayDisplay, rviz::Display)
rviz::ColorProperty * fg_color_property_
rviz::BoolProperty * overtake_color_properties_property_
virtual int getInt() const
rviz::IntProperty * text_size_property_
virtual float getFloat() const
void setMin(int min)
bool isEnabled() const
virtual bool getBool() const
virtual bool isInRegion(int x, int y)
virtual void setPosition(int x, int y)
virtual void addOption(const QString &option, int value=0)
string str
rviz::ColorProperty * bg_color_property_
rviz::IntProperty * width_property_
rviz::BoolProperty * align_bottom_property_
rviz::BoolProperty * overtake_position_properties_property_
rviz::IntProperty * line_width_property_
rviz::RosTopicProperty * update_topic_property_
virtual void movePosition(int x, int y)
rviz::FloatProperty * bg_alpha_property_
std::string getTopicStd() const
virtual int getOptionInt()
virtual void update(float wall_dt, float ros_dt)
rviz::IntProperty * height_property_
rviz::FloatProperty * fg_alpha_property_
void processMessage(const std_msgs::String::ConstPtr &msg)


jsk_rviz_plugins
Author(s): Kei Okada , Yohei Kakiuchi , Shohei Fujii , Ryohei Ueda
autogenerated on Sat Mar 20 2021 03:03:18