display_group.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2012, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <stdio.h> // for debug-write printf
00031 
00032 #include <QColor>
00033 
00034 #include "rviz/display_context.h"
00035 #include "rviz/display_factory.h"
00036 #include "rviz/failed_display.h"
00037 #include "rviz/properties/property_tree_model.h"
00038 
00039 #include "display_group.h"
00040 
00041 namespace rviz
00042 {
00043 
00044 DisplayGroup::DisplayGroup()
00045 {
00046 }
00047 
00048 DisplayGroup::~DisplayGroup()
00049 {
00050   removeAllDisplays();
00051 }
00052 
00053 Qt::ItemFlags DisplayGroup::getViewFlags( int column ) const
00054 {
00055   return Display::getViewFlags( column ) | Qt::ItemIsDropEnabled;
00056 }
00057 
00058 void DisplayGroup::load( const Config& config )
00059 {
00060   removeAllDisplays(); // Only remove Display children, property children must stay.
00061 
00062   // Load Property values, plus name and enabled/disabled.
00063   Display::load( config );
00064 
00065   // Now load Displays.
00066   Config display_list_config = config.mapGetChild( "Displays" );
00067   int num_displays = display_list_config.listLength();
00068 
00069   if( num_displays == 0 )
00070     return;
00071 
00072   if( model_ )
00073   {
00074     model_->beginInsert( this, Display::numChildren(), num_displays );
00075   }
00076 
00077   std::map<Display*,Config> display_config_map;
00078 
00079   // The following two-step loading procedure was motivated by the
00080   // 'display group visibility' property, which needs all other displays
00081   // to be created and named before it can load its settings.
00082 
00083   // hersh says: Is this really necessary?  Can't we make
00084   // DisplayGroupVisibilityProperty self-sufficient in this regard?
00085   // Also, does it really work?  What about saving and loading a
00086   // hierarchy of Displays, will they really all have the right
00087   // visibility settings?
00088 
00089   // first, create all displays and set their names
00090   for( int i = 0; i < num_displays; i++ )
00091   {
00092     Config display_config = display_list_config.listChildAt( i );
00093     QString display_class = "(no class name found)";
00094     display_config.mapGetString( "Class", &display_class );
00095     Display* disp = createDisplay( display_class );
00096     addDisplayWithoutSignallingModel( disp );
00097     QString display_name;
00098     display_config.mapGetString( "Name", &display_name );
00099     disp->setObjectName( display_name );
00100 
00101     display_config_map[ disp ] = display_config;
00102   }
00103 
00104   // now, initialize all displays and load their properties.
00105   for( std::map<Display*,Config>::iterator it = display_config_map.begin(); it != display_config_map.end(); ++it )
00106   {
00107     Config display_config = it->second;
00108     Display* disp = it->first;
00109     disp->initialize( context_ );
00110     disp->load( display_config );
00111   }
00112 
00113   if( model_ )
00114   {
00115     model_->endInsert();
00116   }
00117 }
00118 
00119 Display* DisplayGroup::createDisplay( const QString& class_id )
00120 {
00121   DisplayFactory* factory = context_->getDisplayFactory();
00122   QString error;
00123   Display* disp = factory->make( class_id, &error );
00124   if( !disp )
00125   {
00126     return new FailedDisplay( class_id, error );
00127   }
00128   return disp;
00129 }
00130 
00131 void DisplayGroup::onEnableChanged()
00132 {
00133   Display::onEnableChanged();
00134   for( int i = displays_.size() - 1; i >= 0; i-- )
00135   {
00136     displays_[ i ]->onEnableChanged();
00137   }
00138 }
00139 
00140 void DisplayGroup::save( Config config ) const
00141 {
00142   Display::save( config );
00143 
00144   // Save Displays in a sequence under the key "Displays".
00145   Config display_list_config = config.mapMakeChild( "Displays" );
00146 
00147   int num_displays = displays_.size();
00148   for( int i = 0; i < num_displays; i++ )
00149   {
00150     displays_.at( i )->save( display_list_config.listAppendNew() );
00151   }
00152 }
00153 
00154 void DisplayGroup::removeAllDisplays()
00155 {
00156   if(displays_.size() == 0)
00157     return;
00158 
00159   int num_non_display_children = Display::numChildren();
00160 
00161   if( model_ )
00162   {
00163     model_->beginRemove( this, num_non_display_children, displays_.size() );
00164   }
00165   for( int i = displays_.size() - 1; i >= 0; i-- )
00166   {
00167     Display* child = displays_.takeAt( i );
00168     Q_EMIT displayRemoved( child );
00169     child->setParent( NULL ); // prevent child destructor from calling getParent()->takeChild().
00170     child->setModel( NULL );
00171     child_indexes_valid_ = false;
00172     delete child;
00173   }
00174   if( model_ )
00175   {
00176     model_->endRemove();
00177   }
00178   Q_EMIT childListChanged( this );
00179 }
00180 
00181 Display* DisplayGroup::takeDisplay( Display* child )
00182 {
00183   Display* result = NULL;
00184   int num_displays = displays_.size();
00185   for( int i = 0; i < num_displays; i++ )
00186   {
00187     if( displays_.at( i ) == child )
00188     {
00189       if( model_ )
00190       {
00191         model_->beginRemove( this, Display::numChildren() + i, 1 );
00192       }
00193       result = displays_.takeAt( i );
00194       Q_EMIT displayRemoved( result );
00195       result->setParent( NULL );
00196       result->setModel( NULL );
00197       child_indexes_valid_ = false;
00198       if( model_ )
00199       {
00200         model_->endRemove();
00201       }
00202       Q_EMIT childListChanged( this );
00203       break;
00204     }
00205   }
00206   return result;
00207 }
00208 
00209 Display* DisplayGroup::getDisplayAt( int index ) const
00210 {
00211   if( 0 <= index && index < displays_.size() )
00212   {
00213     return displays_.at( index );
00214   }
00215   return NULL;
00216 }
00217 
00218 DisplayGroup* DisplayGroup::getGroupAt( int index ) const
00219 {
00220   return qobject_cast<DisplayGroup*>( getDisplayAt( index ));
00221 }
00222 
00223 void DisplayGroup::fixedFrameChanged()
00224 {
00225   int num_children = displays_.size();
00226   for( int i = 0; i < num_children; i++ )
00227   {
00228     displays_.at( i )->setFixedFrame( fixed_frame_ );
00229   }  
00230 }
00231 
00232 void DisplayGroup::update( float wall_dt, float ros_dt )
00233 {
00234   int num_children = displays_.size();
00235   for( int i = 0; i < num_children; i++ )
00236   {
00237     Display* display = displays_.at( i );
00238     if( display->isEnabled() )
00239     {
00240       display->update( wall_dt, ros_dt );
00241     }
00242   }  
00243 }
00244 
00245 void DisplayGroup::reset()
00246 {
00247   Display::reset();
00248 
00249   int num_children = displays_.size();
00250   for( int i = 0; i < num_children; i++ )
00251   {
00252     displays_.at( i )->reset();
00253   }  
00254 }
00255 
00256 void DisplayGroup::addDisplayWithoutSignallingModel( Display* child )
00257 {
00258 //  printf("  displaygroup4 displays_.append( child )\n" );
00259   displays_.append( child );
00260   child_indexes_valid_ = false;
00261   child->setModel( model_ );
00262   child->setParent( this );
00263   Q_EMIT displayAdded( child );
00264 }
00265 
00266 void DisplayGroup::addDisplay( Display* child )
00267 {
00268   if( model_ )
00269   {
00270     model_->beginInsert( this, numChildren(), 1 );
00271   }
00272   addDisplayWithoutSignallingModel( child );
00273   if( model_ )
00274   {
00275     model_->endInsert();
00276   }
00277   Q_EMIT childListChanged( this );
00278 }
00279 
00280 void DisplayGroup::addChild( Property* child, int index )
00281 {
00282   Display* display = qobject_cast<Display*>( child );
00283   if( !display )
00284   {
00285     Display::addChild( child, index );
00286     return;
00287   }
00288   if( index < 0 || index > numChildren() )
00289   {
00290     index = numChildren();
00291   }
00292   int disp_index = index - Display::numChildren();
00293   if( disp_index < 0 )
00294   {
00295     disp_index = 0;
00296   }
00297   if( model_ )
00298   {
00299     model_->beginInsert( this, index );
00300   }
00301 
00302   displays_.insert( disp_index, display );
00303   Q_EMIT displayAdded( display );
00304   child_indexes_valid_ = false;
00305   display->setModel( model_ );
00306   display->setParent( this );
00307 
00308   if( model_ )
00309   {
00310     model_->endInsert();
00311   }
00312   Q_EMIT childListChanged( this );
00313 }
00314 
00315 Property* DisplayGroup::takeChildAt( int index )
00316 {
00317   if( index < Display::numChildren() )
00318   {
00319     return Display::takeChildAt( index );
00320   }
00321   int disp_index = index - Display::numChildren();
00322   if( model_ )
00323   {
00324     model_->beginRemove( this, index, 1 );
00325   }
00326 //  printf("  displaygroup5 displays_.takeAt( %d ) ( index = %d )\n", disp_index, index );
00327   Display* child = displays_.takeAt( disp_index );
00328   Q_EMIT displayRemoved( child );
00329   child->setModel( NULL );
00330   child->setParent( NULL );
00331   child_indexes_valid_ = false;
00332   if( model_ )
00333   {
00334     model_->endRemove();
00335   }
00336   Q_EMIT childListChanged( this );
00337   return child;
00338 }
00339 
00340 int DisplayGroup::numDisplays() const
00341 {
00342   return displays_.size();
00343 }
00344 
00345 int DisplayGroup::numChildren() const
00346 {
00347   return Display::numChildren() + displays_.size();
00348 }
00349 
00350 Property* DisplayGroup::childAtUnchecked( int index ) const
00351 {
00352   int first_child_count = Display::numChildren();
00353   if( index < first_child_count )
00354   {
00355     return Display::childAtUnchecked( index );
00356   }
00357   index -= first_child_count;
00358   return displays_.at( index );
00359 }
00360 
00361 } // end namespace rviz


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Tue Oct 3 2017 03:19:30