00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "overlay_text_display.h"
00037 #include <OGRE/OgreMaterialManager.h>
00038 #include <rviz/uniform_string_stream.h>
00039 #include <OGRE/OgreTexture.h>
00040 #include <OGRE/OgreHardwarePixelBuffer.h>
00041 #include <QPainter>
00042
00043 namespace jsk_rviz_plugins
00044 {
00045 OverlayTextDisplay::OverlayTextDisplay() : Display(),
00046 texture_width_(0), texture_height_(0),
00047 text_size_(14),
00048 line_width_(2),
00049 text_(""), font_(""),
00050 bg_color_(0, 0, 0, 0),
00051 fg_color_(255, 255, 255, 255.0),
00052 require_update_texture_(false)
00053 {
00054 update_topic_property_ = new rviz::RosTopicProperty(
00055 "Topic", "",
00056 ros::message_traits::datatype<jsk_rviz_plugins::OverlayText>(),
00057 "jsk_rviz_plugins::OverlayText topic to subscribe to.",
00058 this, SLOT( updateTopic() ));
00059 overtake_position_properties_property_ = new rviz::BoolProperty(
00060 "Overtake Position Properties", false,
00061 "overtake position properties specified by message such as left, top and font",
00062 this, SLOT(updateOvertakePositionProperties()));
00063 overtake_color_properties_property_ = new rviz::BoolProperty(
00064 "Overtake Color Properties", false,
00065 "overtake color properties specified by message such as left, top and font",
00066 this, SLOT(updateOvertakeColorProperties()));
00067 top_property_ = new rviz::IntProperty(
00068 "top", 0,
00069 "top position",
00070 this, SLOT(updateTop()));
00071 top_property_->setMin(0);
00072 left_property_ = new rviz::IntProperty(
00073 "left", 0,
00074 "left position",
00075 this, SLOT(updateLeft()));
00076 left_property_->setMin(0);
00077 width_property_ = new rviz::IntProperty(
00078 "width", 128,
00079 "width position",
00080 this, SLOT(updateWidth()));
00081 width_property_->setMin(0);
00082 height_property_ = new rviz::IntProperty(
00083 "height", 128,
00084 "height position",
00085 this, SLOT(updateHeight()));
00086 height_property_->setMin(0);
00087 text_size_property_ = new rviz::IntProperty(
00088 "text size", 12,
00089 "text size",
00090 this, SLOT(updateTextSize()));
00091 text_size_property_->setMin(0);
00092 line_width_property_ = new rviz::IntProperty(
00093 "line width", 2,
00094 "line width",
00095 this, SLOT(updateLineWidth()));
00096 line_width_property_->setMin(0);
00097 fg_color_property_ = new rviz::ColorProperty(
00098 "Foreground Color", QColor(25, 255, 240),
00099 "Foreground Color",
00100 this, SLOT(updateFGColor()));
00101 fg_alpha_property_ = new rviz::FloatProperty(
00102 "Foreground Alpha", 0.8, "Foreground Alpha",
00103 this, SLOT(updateFGAlpha()));
00104 fg_alpha_property_->setMin(0.0);
00105 fg_alpha_property_->setMax(1.0);
00106 bg_color_property_ = new rviz::ColorProperty(
00107 "Background Color", QColor(0, 0, 0),
00108 "Background Color",
00109 this, SLOT(updateBGColor()));
00110 bg_alpha_property_ = new rviz::FloatProperty(
00111 "Background Alpha", 0.8, "Background Alpha",
00112 this, SLOT(updateBGAlpha()));
00113 bg_alpha_property_->setMin(0.0);
00114 bg_alpha_property_->setMax(1.0);
00115 font_property_ = new rviz::StringProperty(
00116 "font", "DejaVu Sans Mono",
00117 "font", this,
00118 SLOT(updateFont()));
00119 }
00120
00121 OverlayTextDisplay::~OverlayTextDisplay()
00122 {
00123 onDisable();
00124
00125 delete update_topic_property_;
00126 delete overtake_color_properties_property_;
00127 delete overtake_position_properties_property_;
00128 delete top_property_;
00129 delete left_property_;
00130 delete width_property_;
00131 delete height_property_;
00132 delete text_size_property_;
00133 delete line_width_property_;
00134 delete bg_color_property_;
00135 delete bg_alpha_property_;
00136 delete fg_color_property_;
00137 delete fg_alpha_property_;
00138 delete font_property_;
00139 }
00140
00141 void OverlayTextDisplay::onEnable()
00142 {
00143 if (overlay_) {
00144 overlay_->show();
00145 }
00146 subscribe();
00147 }
00148
00149 void OverlayTextDisplay::onDisable()
00150 {
00151 if (overlay_) {
00152 overlay_->hide();
00153 }
00154 unsubscribe();
00155 }
00156
00157 void OverlayTextDisplay::unsubscribe()
00158 {
00159 sub_.shutdown();
00160 }
00161
00162 void OverlayTextDisplay::subscribe()
00163 {
00164 std::string topic_name = update_topic_property_->getTopicStd();
00165 if (topic_name.length() > 0 && topic_name != "/") {
00166 sub_ = ros::NodeHandle().subscribe(topic_name, 1, &OverlayTextDisplay::processMessage, this);
00167 }
00168 }
00169
00170 void OverlayTextDisplay::updateTopic()
00171 {
00172 unsubscribe();
00173 subscribe();
00174 }
00175
00176
00177 void OverlayTextDisplay::onInitialize()
00178 {
00179 onEnable();
00180 updateTopic();
00181 updateOvertakePositionProperties();
00182 updateOvertakeColorProperties();
00183 updateTop();
00184 updateLeft();
00185 updateWidth();
00186 updateHeight();
00187 updateTextSize();
00188 updateFGColor();
00189 updateFGAlpha();
00190 updateBGColor();
00191 updateBGAlpha();
00192 updateFont();
00193 updateLineWidth();
00194 require_update_texture_ = true;
00195 }
00196
00197 void OverlayTextDisplay::update(float wall_dt, float ros_dt)
00198 {
00199 if (!require_update_texture_) {
00200 return;
00201 }
00202 if (!isEnabled()) {
00203 return;
00204 }
00205 if (!overlay_) {
00206 return;
00207 }
00208 overlay_->updateTextureSize(texture_width_, texture_height_);
00209 {
00210 ScopedPixelBuffer buffer = overlay_->getBuffer();
00211 QImage Hud = buffer.getQImage(*overlay_, bg_color_);
00212 QPainter painter( &Hud );
00213 painter.setRenderHint(QPainter::Antialiasing, true);
00214 painter.setPen(QPen(fg_color_, line_width_ || 1, Qt::SolidLine));
00215 uint16_t w = overlay_->getTextureWidth();
00216 uint16_t h = overlay_->getTextureHeight();
00217
00218
00219 if (text_size_ != 0) {
00220
00221 QFont font(font_.length() > 0 ? font_.c_str(): "Arial");
00222 font.setPointSize(text_size_);
00223 font.setBold(true);
00224 painter.setFont(font);
00225 }
00226 if (text_.length() > 0) {
00227
00228 painter.drawText(0, 0, w, h,
00229 Qt::TextWordWrap | Qt::AlignLeft | Qt::AlignTop,
00230 text_.c_str());
00231 }
00232 painter.end();
00233 }
00234 overlay_->setDimensions(overlay_->getTextureWidth(), overlay_->getTextureHeight());
00235 require_update_texture_ = false;
00236 }
00237
00238 void OverlayTextDisplay::processMessage
00239 (const jsk_rviz_plugins::OverlayText::ConstPtr& msg)
00240 {
00241 if (!isEnabled()) {
00242 return;
00243 }
00244 if (!overlay_) {
00245 static int count = 0;
00246 rviz::UniformStringStream ss;
00247 ss << "OverlayTextDisplayObject" << count++;
00248 overlay_.reset(new OverlayObject(ss.str()));
00249 overlay_->show();
00250 }
00251 if (overlay_) {
00252 if (msg->action == jsk_rviz_plugins::OverlayText::DELETE) {
00253 overlay_->hide();
00254 }
00255 else if (msg->action == jsk_rviz_plugins::OverlayText::ADD) {
00256 overlay_->show();
00257 }
00258 }
00259
00260
00261 text_ = msg->text;
00262 if (!overtake_position_properties_) {
00263 texture_width_ = msg->width;
00264 texture_height_ = msg->height;
00265 text_size_ = msg->text_size;
00266 left_ = msg->left;
00267 top_ = msg->top;
00268 }
00269 if (!overtake_color_properties_) {
00270 bg_color_ = QColor(msg->bg_color.r * 255.0,
00271 msg->bg_color.g * 255.0,
00272 msg->bg_color.b * 255.0,
00273 msg->bg_color.a * 255.0);
00274 fg_color_ = QColor(msg->fg_color.r * 255.0,
00275 msg->fg_color.g * 255.0,
00276 msg->fg_color.b * 255.0,
00277 msg->fg_color.a * 255.0);
00278 font_ = msg->font;
00279 line_width_ = msg->line_width;
00280 }
00281 if (overlay_) {
00282 overlay_->setPosition(left_, top_);
00283 }
00284 require_update_texture_ = true;
00285 }
00286
00287 void OverlayTextDisplay::updateOvertakePositionProperties()
00288 {
00289
00290 if (!overtake_position_properties_ &&
00291 overtake_position_properties_property_->getBool()) {
00292 updateTop();
00293 updateLeft();
00294 updateWidth();
00295 updateHeight();
00296 updateTextSize();
00297 require_update_texture_ = true;
00298 }
00299 overtake_position_properties_
00300 = overtake_position_properties_property_->getBool();
00301 if (overtake_position_properties_) {
00302 top_property_->show();
00303 left_property_->show();
00304 width_property_->show();
00305 height_property_->show();
00306 text_size_property_->show();
00307 }
00308 else {
00309 top_property_->hide();
00310 left_property_->hide();
00311 width_property_->hide();
00312 height_property_->hide();
00313 text_size_property_->hide();
00314 }
00315 }
00316
00317 void OverlayTextDisplay::updateOvertakeColorProperties()
00318 {
00319 if (!overtake_color_properties_ &&
00320 overtake_color_properties_property_->getBool()) {
00321
00322 updateFGColor();
00323 updateFGAlpha();
00324 updateBGColor();
00325 updateBGAlpha();
00326 updateFont();
00327 updateLineWidth();
00328 require_update_texture_ = true;
00329 }
00330 overtake_color_properties_ = overtake_color_properties_property_->getBool();
00331 if (overtake_color_properties_) {
00332 fg_color_property_->show();
00333 fg_alpha_property_->show();
00334 bg_color_property_->show();
00335 bg_alpha_property_->show();
00336 line_width_property_->show();
00337 font_property_->show();
00338 }
00339 else {
00340 fg_color_property_->hide();
00341 fg_alpha_property_->hide();
00342 bg_color_property_->hide();
00343 bg_alpha_property_->hide();
00344 line_width_property_->hide();
00345 font_property_->hide();
00346 }
00347 }
00348
00349 void OverlayTextDisplay::updateTop()
00350 {
00351 top_ = top_property_->getInt();
00352 if (overtake_position_properties_) {
00353 require_update_texture_ = true;
00354 }
00355 }
00356
00357 void OverlayTextDisplay::updateLeft()
00358 {
00359 left_ = left_property_->getInt();
00360 if (overtake_position_properties_) {
00361 require_update_texture_ = true;
00362 }
00363 }
00364
00365 void OverlayTextDisplay::updateWidth()
00366 {
00367 texture_width_ = width_property_->getInt();
00368 if (overtake_position_properties_) {
00369 require_update_texture_ = true;
00370 }
00371 }
00372
00373 void OverlayTextDisplay::updateHeight()
00374 {
00375 texture_height_ = height_property_->getInt();
00376 if (overtake_position_properties_) {
00377 require_update_texture_ = true;
00378 }
00379 }
00380
00381 void OverlayTextDisplay::updateTextSize()
00382 {
00383 text_size_ = text_size_property_->getInt();
00384 if (overtake_position_properties_) {
00385 require_update_texture_ = true;
00386 }
00387 }
00388
00389 void OverlayTextDisplay::updateBGColor()
00390 {
00391 QColor c = bg_color_property_->getColor();
00392 bg_color_.setRed(c.red());
00393 bg_color_.setGreen(c.green());
00394 bg_color_.setBlue(c.blue());
00395 if (overtake_color_properties_) {
00396 require_update_texture_ = true;
00397 }
00398 }
00399
00400 void OverlayTextDisplay::updateBGAlpha()
00401 {
00402 bg_color_.setAlpha(bg_alpha_property_->getFloat() * 255.0);
00403 if (overtake_color_properties_) {
00404 require_update_texture_ = true;
00405 }
00406 }
00407
00408 void OverlayTextDisplay::updateFGColor()
00409 {
00410 QColor c = fg_color_property_->getColor();
00411 fg_color_.setRed(c.red());
00412 fg_color_.setGreen(c.green());
00413 fg_color_.setBlue(c.blue());
00414 if (overtake_color_properties_) {
00415 require_update_texture_ = true;
00416 }
00417 }
00418
00419 void OverlayTextDisplay::updateFGAlpha()
00420 {
00421 fg_color_.setAlpha(fg_alpha_property_->getFloat() * 255.0);
00422 if (overtake_color_properties_) {
00423 require_update_texture_ = true;
00424 }
00425 }
00426
00427 void OverlayTextDisplay::updateFont()
00428 {
00429 font_ = font_property_->getStdString();
00430 if (overtake_color_properties_) {
00431 require_update_texture_ = true;
00432 }
00433 }
00434
00435 void OverlayTextDisplay::updateLineWidth()
00436 {
00437 line_width_ = line_width_property_->getInt();
00438 if (overtake_color_properties_) {
00439 require_update_texture_ = true;
00440 }
00441 }
00442 }
00443
00444 #include <pluginlib/class_list_macros.h>
00445 PLUGINLIB_EXPORT_CLASS( jsk_rviz_plugins::OverlayTextDisplay, rviz::Display )