overlay_text_display.cpp
Go to the documentation of this file.
00001 // -*- mode: c++; -*-
00002 /*********************************************************************
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2014, JSK Lab
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/o2r other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the JSK Lab nor the names of its
00019  *     contributors may be used to endorse or promote products derived
00020  *     from this software without specific prior written permission.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  *  POSSIBILITY OF SUCH DAMAGE.
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     //delete overlay_;
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   // only the first time
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       // font
00219       if (text_size_ != 0) {
00220         //QFont font = painter.font();
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         //painter.drawText(0, 0, w, h, Qt::TextWordWrap | Qt::AlignLeft,
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     // store message for update method
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       // read all the parameters from properties
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 )


jsk_rviz_plugins
Author(s): Kei Okada , Yohei Kakiuchi , Shohei Fujii , Ryohei Ueda
autogenerated on Sun Sep 13 2015 22:29:03