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/or 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 
500  bool StringDisplay::isInRegion(int x, int y)
501  {
502  return (top_ < y && top_ + texture_height_ > y &&
503  left_ < x && left_ + texture_width_ > x);
504  }
505 
506  void StringDisplay::movePosition(int x, int y)
507  {
508  top_ = y;
509  left_ = x;
510  }
511 
512  void StringDisplay::setPosition(int x, int y)
513  {
516  }
517 
518 } // namespace jsk_rviz_plugins
519 
void setMin(float min)
#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)
virtual QColor getColor() const
rviz::ColorProperty * fg_color_property_
rviz::BoolProperty * overtake_color_properties_property_
rviz::IntProperty * text_size_property_
void setMin(int min)
std::string getTopicStd() const
virtual bool isInRegion(int x, int y)
virtual void setPosition(int x, int y)
virtual void addOption(const QString &option, int value=0)
rviz::ColorProperty * bg_color_property_
rviz::IntProperty * width_property_
rviz::BoolProperty * align_bottom_property_
rviz::BoolProperty * overtake_position_properties_property_
virtual int getInt() const
bool isEnabled() const
bool setValue(const QVariant &new_value) override
rviz::IntProperty * line_width_property_
string str
w
virtual float getFloat() const
rviz::RosTopicProperty * update_topic_property_
virtual void movePosition(int x, int y)
rviz::FloatProperty * bg_alpha_property_
virtual bool getBool() 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 Thu Jun 1 2023 02:45:58