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 #include "property.h"
00031 #include "ros_topic_property.h"
00032 #include "tf_frame_property.h"
00033 #include "edit_enum_property.h"
00034
00035 #include <wx/wx.h>
00036 #include <wx/propgrid/propgrid.h>
00037 #include <wx/propgrid/advprops.h>
00038 #include <wx/config.h>
00039
00040 namespace rviz
00041 {
00042
00043 static const wxColour ERROR_COLOR(178, 23, 46);
00044 static const wxColour WARN_COLOR(222, 213, 17);
00045
00046 wxPGProperty* getCategoryPGProperty(const CategoryPropertyWPtr& wprop)
00047 {
00048 CategoryPropertyPtr prop = wprop.lock();
00049
00050 if (prop)
00051 {
00052 return prop->getPGProperty();
00053 }
00054
00055 return NULL;
00056 }
00057
00058 void setPropertyHelpText(wxPGProperty* property, const std::string& text)
00059 {
00060 if (property)
00061 {
00062 property->SetHelpString(wxString::FromAscii(text.c_str()));
00063 }
00064 }
00065
00066 void setPropertyToColors(wxPGProperty* property, const wxColour& fg_color, const wxColour& bg_color, uint32_t column)
00067 {
00068 if (!property)
00069 {
00070 return;
00071 }
00072
00073 wxPGCell* cell = property->GetCell( column );
00074 if ( !cell )
00075 {
00076 cell = new wxPGCell( *(wxString*)0, wxNullBitmap, *wxLIGHT_GREY, *wxGREEN );
00077 property->SetCell( column, cell );
00078 }
00079
00080 cell->SetFgCol(fg_color);
00081 cell->SetBgCol(bg_color);
00082 }
00083
00084 void setPropertyToError(wxPGProperty* property, uint32_t column)
00085 {
00086 setPropertyToColors(property, *wxWHITE, ERROR_COLOR, column);
00087 }
00088
00089 void setPropertyToWarn(wxPGProperty* property, uint32_t column)
00090 {
00091 setPropertyToColors(property, *wxWHITE, WARN_COLOR, column);
00092 }
00093
00094 void setPropertyToOK(wxPGProperty* property, uint32_t column)
00095 {
00096 setPropertyToColors(property, wxNullColour, wxNullColour, column);
00097 }
00098
00099 void setPropertyToDisabled(wxPGProperty* property, uint32_t column)
00100 {
00101 setPropertyToColors(property, wxColour(0x33, 0x44, 0x44), wxColour(0xaa, 0xaa, 0xaa), column);
00102 }
00103
00104 void setPropertyName(wxPGProperty* property, const wxString& name)
00105 {
00106 if (property)
00107 {
00108 property->SetName(name);
00109 }
00110 }
00111
00112 PropertyBase::PropertyBase()
00113 : grid_(NULL)
00114 , property_(NULL)
00115 {
00116
00117 }
00118
00119 PropertyBase::~PropertyBase()
00120 {
00121 if (property_ && grid_)
00122 {
00123 grid_->DeleteProperty( property_ );
00124 }
00125 }
00126
00127 void PropertyBase::setPropertyGrid(wxPropertyGrid* grid)
00128 {
00129 grid_ = grid;
00130 }
00131
00132 void PropertyBase::setPGClientData()
00133 {
00134 if (property_)
00135 {
00136 property_->SetClientData( this );
00137 }
00138 }
00139
00140 void PropertyBase::hide()
00141 {
00142 if (property_)
00143 {
00144 property_->Hide(true);
00145 }
00146 }
00147
00148 void PropertyBase::show()
00149 {
00150 if (property_)
00151 {
00152 property_->Hide(false);
00153 }
00154 }
00155
00156 bool PropertyBase::isSelected()
00157 {
00158 if (property_ && grid_)
00159 {
00160 return grid_->GetSelectedProperty() == property_;
00161 }
00162
00163 return false;
00164 }
00165
00166 StatusProperty::StatusProperty(const std::string& name, const std::string& prefix, const CategoryPropertyWPtr& parent, void* user_data)
00167 : name_(wxString::FromAscii(name.c_str()))
00168 , prefix_(wxString::FromAscii(prefix.c_str()))
00169 , parent_(parent)
00170 , user_data_(user_data)
00171 , top_property_(0)
00172 , enabled_(true)
00173 , prefix_changed_(false)
00174 , top_status_(status_levels::Ok)
00175 {}
00176
00177 StatusProperty::~StatusProperty()
00178 {
00179 if (grid_)
00180 {
00181 if (top_property_)
00182 {
00183 grid_->DeleteProperty(top_property_);
00184 }
00185 }
00186 }
00187
00188 void StatusProperty::enable()
00189 {
00190 boost::mutex::scoped_lock lock(status_mutex_);
00191 enabled_ = true;
00192
00193 changed();
00194 }
00195
00196 void StatusProperty::disable()
00197 {
00198 clear();
00199
00200 boost::mutex::scoped_lock lock(status_mutex_);
00201 enabled_ = false;
00202
00203 changed();
00204 }
00205
00206 void StatusProperty::setPrefix(const std::string& prefix)
00207 {
00208 boost::mutex::scoped_lock lock(status_mutex_);
00209 prefix_ = wxString::FromAscii(prefix.c_str());
00210 prefix_changed_ = true;
00211 changed();
00212 }
00213
00214 void StatusProperty::clear()
00215 {
00216 boost::mutex::scoped_lock lock(status_mutex_);
00217
00218 if (!enabled_)
00219 {
00220 return;
00221 }
00222
00223 M_StringToStatus::iterator it = statuses_.begin();
00224 M_StringToStatus::iterator end = statuses_.end();
00225 for (; it != end; ++it)
00226 {
00227 Status& status = it->second;
00228 status.kill = true;
00229 }
00230
00231
00232 updateTopLevelStatus();
00233
00234 changed();
00235 }
00236
00237 void StatusProperty::updateTopLevelStatus()
00238 {
00239 top_status_ = status_levels::Ok;
00240 M_StringToStatus::iterator it = statuses_.begin();
00241 M_StringToStatus::iterator end = statuses_.end();
00242 for (; it != end; ++it)
00243 {
00244 Status& status = it->second;
00245
00246 if (status.kill)
00247 {
00248 continue;
00249 }
00250
00251 if (status.level > top_status_)
00252 {
00253 top_status_ = status.level;
00254 }
00255 }
00256 }
00257
00258 void StatusProperty::setStatus(StatusLevel level, const std::string& name, const std::string& text)
00259 {
00260 boost::mutex::scoped_lock lock(status_mutex_);
00261
00262 if (!enabled_)
00263 {
00264 return;
00265 }
00266
00267 Status& status = statuses_[name];
00268 wxString wx_name = wxString::FromAscii(name.c_str());
00269 wxString wx_text = wxString::FromAscii(text.c_str());
00270
00271
00272 if (status.level == level && status.text == wx_text && !status.kill)
00273 {
00274 return;
00275 }
00276
00277 status.name = wx_name;
00278 status.text = wx_text;
00279 status.level = level;
00280 status.kill = false;
00281
00282
00283 updateTopLevelStatus();
00284
00285 changed();
00286 }
00287
00288 void StatusProperty::deleteStatus(const std::string& name)
00289 {
00290 boost::mutex::scoped_lock lock(status_mutex_);
00291
00292 if (!enabled_)
00293 {
00294 return;
00295 }
00296
00297 M_StringToStatus::iterator it = statuses_.find(name);
00298 if (it != statuses_.end())
00299 {
00300 Status& status = it->second;
00301 status.kill = true;
00302 }
00303
00304
00305 updateTopLevelStatus();
00306
00307 changed();
00308 }
00309
00310 void StatusProperty::writeToGrid()
00311 {
00312 boost::mutex::scoped_lock lock(status_mutex_);
00313
00314 if ( !top_property_ )
00315 {
00316 wxString top_name = name_ + wxT("TopStatus");
00317
00318 if ( parent_.lock() )
00319 {
00320 top_property_ = grid_->AppendIn( getCategoryPGProperty(parent_), new wxPropertyCategory(name_, prefix_ + top_name) );
00321 }
00322 else
00323 {
00324 top_property_ = grid_->AppendIn( grid_->GetRoot(), new wxPropertyCategory(name_, prefix_ + top_name));
00325 }
00326
00327 top_property_->SetClientData( this );
00328
00329 grid_->DisableProperty(top_property_);
00330 grid_->Collapse(top_property_);
00331 }
00332
00333 if (prefix_changed_)
00334 {
00335 top_property_->SetName(prefix_ + name_);
00336 }
00337
00338 bool expanded = top_property_->IsExpanded();
00339
00340 top_status_ = status_levels::Ok;
00341
00342 std::vector<std::string> to_erase;
00343 M_StringToStatus::iterator it = statuses_.begin();
00344 M_StringToStatus::iterator end = statuses_.end();
00345 for (; it != end; ++it)
00346 {
00347 Status& status = it->second;
00348
00349 if (status.kill)
00350 {
00351 to_erase.push_back(it->first);
00352 continue;
00353 }
00354
00355 if (!status.property)
00356 {
00357 status.property = grid_->AppendIn(top_property_, new wxStringProperty(status.name, prefix_ + name_ + status.name, status.text) );
00358 }
00359 else if (prefix_changed_)
00360 {
00361 status.property->SetName(prefix_ + name_ + status.name);
00362 }
00363
00364 if (status.level > top_status_)
00365 {
00366 top_status_ = status.level;
00367 }
00368
00369 if (enabled_)
00370 {
00371 switch (status.level)
00372 {
00373 case status_levels::Ok:
00374 setPropertyToOK(status.property);
00375 break;
00376 case status_levels::Warn:
00377 setPropertyToColors(status.property, WARN_COLOR, *wxWHITE);
00378
00379 break;
00380 case status_levels::Error:
00381 setPropertyToColors(status.property, ERROR_COLOR, *wxWHITE);
00382
00383 break;
00384 }
00385 }
00386 else
00387 {
00388 setPropertyToDisabled(status.property);
00389 }
00390
00391 grid_->SetPropertyValue(status.property, status.text);
00392 status.property->SetHelpString(status.text);
00393 }
00394
00395 std::vector<std::string>::iterator kill_it = to_erase.begin();
00396 std::vector<std::string>::iterator kill_end = to_erase.end();
00397 for (; kill_it != kill_end; ++kill_it)
00398 {
00399 Status& status = statuses_[*kill_it];
00400 if (status.property)
00401 {
00402 grid_->DeleteProperty(status.property);
00403 }
00404
00405 statuses_.erase(*kill_it);
00406 }
00407
00408 if (!expanded)
00409 {
00410 grid_->Collapse(top_property_);
00411 }
00412
00413 wxString label;
00414 if (enabled_)
00415 {
00416 switch (top_status_)
00417 {
00418 case status_levels::Ok:
00419 setPropertyToColors(top_property_, *wxBLACK, *wxWHITE);
00420
00421 label = name_ + wxT(": OK");
00422 break;
00423 case status_levels::Warn:
00424 setPropertyToColors(top_property_, WARN_COLOR, *wxWHITE);
00425
00426 label = name_ + wxT(": Warning");
00427 break;
00428 case status_levels::Error:
00429 setPropertyToColors(top_property_, ERROR_COLOR, *wxWHITE);
00430
00431 label = name_ + wxT(": Error");
00432 break;
00433 }
00434 }
00435 else
00436 {
00437 setPropertyToDisabled(top_property_);
00438 label = name_ + wxT(": Disabled");
00439 }
00440
00441 grid_->SetPropertyLabel(top_property_, label);
00442 wxPGCell* cell = top_property_->GetCell( 0 );
00443 if ( cell )
00444 {
00445
00446 }
00447
00448 grid_->Sort(top_property_);
00449 }
00450
00451 StatusLevel StatusProperty::getTopLevelStatus()
00452 {
00453 return top_status_;
00454 }
00455
00456 void StatusProperty::setPGClientData()
00457 {
00458 if (top_property_)
00459 {
00460 top_property_->SetClientData( this );
00461 }
00462 }
00463
00464 void BoolProperty::writeToGrid()
00465 {
00466 if ( !property_ )
00467 {
00468 property_ = grid_->AppendIn( getCategoryPGProperty(parent_), new wxBoolProperty( name_, prefix_ + name_, get() ) );
00469 property_->SetAttribute( wxPG_BOOL_USE_CHECKBOX, true );
00470
00471 if ( !hasSetter() )
00472 {
00473 grid_->DisableProperty( property_ );
00474 }
00475 }
00476 else
00477 {
00478 grid_->SetPropertyValue(property_, get());
00479 }
00480
00481 setPropertyHelpText(property_, help_text_);
00482 }
00483
00484 void BoolProperty::readFromGrid()
00485 {
00486 wxVariant var = property_->GetValue();
00487 set( var.GetBool() );
00488 }
00489
00490 void BoolProperty::saveToConfig( wxConfigBase* config )
00491 {
00492 config->Write( prefix_ + name_, (int)get() );
00493 }
00494
00495 void BoolProperty::loadFromConfig( wxConfigBase* config )
00496 {
00497 bool val;
00498 if (!config->Read( prefix_ + name_, &val, get() ))
00499 {
00500 V_wxString::iterator it = legacy_names_.begin();
00501 V_wxString::iterator end = legacy_names_.end();
00502 for (; it != end; ++it)
00503 {
00504 if (config->Read( prefix_ + *it, &val, get() ))
00505 {
00506 break;
00507 }
00508 }
00509 }
00510
00511 set( val );
00512 }
00513
00514 void IntProperty::setMin( int min )
00515 {
00516 if (property_)
00517 {
00518 property_->SetAttribute( wxT("Min"), min );
00519 }
00520 }
00521
00522 void IntProperty::setMax( int max )
00523 {
00524 if (property_)
00525 {
00526 property_->SetAttribute( wxT("Max"), max );
00527 }
00528 }
00529
00530 void IntProperty::writeToGrid()
00531 {
00532 if ( !property_ )
00533 {
00534 property_ = grid_->AppendIn( getCategoryPGProperty(parent_), new wxIntProperty( name_, prefix_ + name_, get() ) );
00535
00536 if ( !hasSetter() )
00537 {
00538 grid_->DisableProperty( property_ );
00539 }
00540 }
00541 else
00542 {
00543 grid_->SetPropertyValue(property_, (long)get());
00544 }
00545
00546 setPropertyHelpText(property_, help_text_);
00547 }
00548
00549 void IntProperty::readFromGrid()
00550 {
00551 wxVariant var = property_->GetValue();
00552 set( var.GetLong() );
00553 }
00554
00555 void IntProperty::saveToConfig( wxConfigBase* config )
00556 {
00557 config->Write( prefix_ + name_, (int)get() );
00558 }
00559
00560 void IntProperty::loadFromConfig( wxConfigBase* config )
00561 {
00562 long val;
00563 if (!config->Read( prefix_ + name_, &val, get() ))
00564 {
00565 V_wxString::iterator it = legacy_names_.begin();
00566 V_wxString::iterator end = legacy_names_.end();
00567 for (; it != end; ++it)
00568 {
00569 if (config->Read( prefix_ + *it, &val, get() ))
00570 {
00571 break;
00572 }
00573 }
00574 }
00575
00576 set( val );
00577 }
00578
00579 void FloatProperty::setMin( float min )
00580 {
00581 if (property_)
00582 {
00583 property_->SetAttribute( wxT("Min"), min );
00584 }
00585 }
00586
00587 void FloatProperty::setMax( float max )
00588 {
00589 if (property_)
00590 {
00591 property_->SetAttribute( wxT("Max"), max );
00592 }
00593 }
00594
00595
00596 void FloatProperty::writeToGrid()
00597 {
00598 if ( !property_ )
00599 {
00600 property_ = grid_->AppendIn( getCategoryPGProperty(parent_), new wxFloatProperty( name_, prefix_ + name_, get() ) );
00601
00602 if ( !hasSetter() )
00603 {
00604 grid_->DisableProperty( property_ );
00605 }
00606 }
00607 else
00608 {
00609 grid_->SetPropertyValue(property_, (double)get());
00610 }
00611
00612 setPropertyHelpText(property_, help_text_);
00613 }
00614
00615 void FloatProperty::readFromGrid()
00616 {
00617 wxVariant var = property_->GetValue();
00618 set( var.GetDouble() );
00619 }
00620
00621 void FloatProperty::saveToConfig( wxConfigBase* config )
00622 {
00623 config->Write( prefix_ + name_, (float)get() );
00624 }
00625
00626 void FloatProperty::loadFromConfig( wxConfigBase* config )
00627 {
00628 double val;
00629 if (!config->Read( prefix_ + name_, &val, get() ))
00630 {
00631 V_wxString::iterator it = legacy_names_.begin();
00632 V_wxString::iterator end = legacy_names_.end();
00633 for (; it != end; ++it)
00634 {
00635 if (config->Read( prefix_ + *it, &val, get() ))
00636 {
00637 break;
00638 }
00639 }
00640 }
00641
00642 set( val );
00643 }
00644
00645 void DoubleProperty::setMin( double min )
00646 {
00647 if (property_)
00648 {
00649 property_->SetAttribute( wxT("Min"), min );
00650 }
00651 }
00652
00653 void DoubleProperty::setMax( double max )
00654 {
00655 if (property_)
00656 {
00657 property_->SetAttribute( wxT("Max"), max );
00658 }
00659 }
00660
00661
00662 void DoubleProperty::writeToGrid()
00663 {
00664 if ( !property_ )
00665 {
00666 property_ = grid_->AppendIn( getCategoryPGProperty(parent_), new wxFloatProperty( name_, prefix_ + name_, get() ) );
00667
00668 if ( !hasSetter() )
00669 {
00670 grid_->DisableProperty( property_ );
00671 }
00672 }
00673 else
00674 {
00675 grid_->SetPropertyValue(property_, (double)get());
00676 }
00677
00678 setPropertyHelpText(property_, help_text_);
00679 }
00680
00681 void DoubleProperty::readFromGrid()
00682 {
00683 wxVariant var = property_->GetValue();
00684 set( var.GetDouble() );
00685 }
00686
00687 void DoubleProperty::saveToConfig( wxConfigBase* config )
00688 {
00689 config->Write( prefix_ + name_, (float)get() );
00690 }
00691
00692 void DoubleProperty::loadFromConfig( wxConfigBase* config )
00693 {
00694 double val;
00695 if (!config->Read( prefix_ + name_, &val, get() ))
00696 {
00697 V_wxString::iterator it = legacy_names_.begin();
00698 V_wxString::iterator end = legacy_names_.end();
00699 for (; it != end; ++it)
00700 {
00701 if (config->Read( prefix_ + *it, &val, get() ))
00702 {
00703 break;
00704 }
00705 }
00706 }
00707
00708 set( val );
00709 }
00710
00711 void StringProperty::writeToGrid()
00712 {
00713 if ( !property_ )
00714 {
00715 property_ = grid_->AppendIn( getCategoryPGProperty(parent_), new wxStringProperty( name_, prefix_ + name_, wxString::FromAscii( get().c_str() ) ) );
00716
00717 if ( !hasSetter() )
00718 {
00719 grid_->DisableProperty( property_ );
00720 }
00721 }
00722 else
00723 {
00724 grid_->SetPropertyValue(property_, wxString::FromAscii( get().c_str() ));
00725 }
00726
00727 setPropertyHelpText(property_, help_text_);
00728 }
00729
00730 void StringProperty::readFromGrid()
00731 {
00732 wxVariant var = property_->GetValue();
00733 set( (const char*)var.GetString().mb_str() );
00734 }
00735
00736 void StringProperty::saveToConfig( wxConfigBase* config )
00737 {
00738 config->Write( prefix_ + name_, wxString::FromAscii( get().c_str() ) );
00739 }
00740
00741 void StringProperty::loadFromConfig( wxConfigBase* config )
00742 {
00743 wxString val;
00744 if (!config->Read( prefix_ + name_, &val, wxString::FromAscii( get().c_str() ) ))
00745 {
00746 V_wxString::iterator it = legacy_names_.begin();
00747 V_wxString::iterator end = legacy_names_.end();
00748 for (; it != end; ++it)
00749 {
00750 if (config->Read( prefix_ + *it, &val, wxString::FromAscii( get().c_str() ) ))
00751 {
00752 break;
00753 }
00754 }
00755 }
00756
00757 set( (const char*)val.mb_str() );
00758 }
00759
00760 void ROSTopicStringProperty::setMessageType(const std::string& message_type)
00761 {
00762 message_type_ = message_type;
00763 ros_topic_property_->setMessageType(message_type);
00764 }
00765
00766 void ROSTopicStringProperty::writeToGrid()
00767 {
00768 if ( !property_ )
00769 {
00770 ros_topic_property_ = new ROSTopicProperty( message_type_, name_, prefix_ + name_, wxString::FromAscii( get().c_str() ) );
00771 property_ = grid_->AppendIn( getCategoryPGProperty(parent_), ros_topic_property_ );
00772
00773 if ( !hasSetter() )
00774 {
00775 grid_->DisableProperty( property_ );
00776 }
00777 }
00778 else
00779 {
00780 grid_->SetPropertyValue(property_, wxString::FromAscii( get().c_str() ));
00781 }
00782
00783 setPropertyHelpText(property_, help_text_);
00784 }
00785
00786 void ColorProperty::writeToGrid()
00787 {
00788 if ( !property_ )
00789 {
00790 Color c = get();
00791 property_ = grid_->AppendIn( getCategoryPGProperty(parent_), new wxColourProperty( name_, prefix_ + name_, wxColour( c.r_ * 255, c.g_ * 255, c.b_ * 255 ) ) );
00792
00793 if ( !hasSetter() )
00794 {
00795 grid_->DisableProperty( property_ );
00796 }
00797 }
00798 else
00799 {
00800 Color c = get();
00801 wxVariant var;
00802 var << wxColour( c.r_ * 255, c.g_ * 255, c.b_ * 255 );
00803 grid_->SetPropertyValue(property_, var);
00804 }
00805
00806 setPropertyHelpText(property_, help_text_);
00807 }
00808
00809 void ColorProperty::readFromGrid()
00810 {
00811 wxVariant var = property_->GetValue();
00812 wxColour col;
00813 col << var;
00814 set( Color( col.Red() / 255.0f, col.Green() / 255.0f, col.Blue() / 255.0f ) );
00815 }
00816
00817 void ColorProperty::saveToConfig( wxConfigBase* config )
00818 {
00819 Color c = get();
00820
00821 config->Write( prefix_ + name_ + wxT("R"), c.r_ );
00822 config->Write( prefix_ + name_ + wxT("G"), c.g_ );
00823 config->Write( prefix_ + name_ + wxT("B"), c.b_ );
00824 }
00825
00826 void ColorProperty::loadFromConfig( wxConfigBase* config )
00827 {
00828 Color c = get();
00829 double r, g, b;
00830 bool found = true;
00831 found &= config->Read( prefix_ + name_ + wxT("R"), &r, c.r_ );
00832 found &= config->Read( prefix_ + name_ + wxT("G"), &g, c.g_ );
00833 found &= config->Read( prefix_ + name_ + wxT("B"), &b, c.b_ );
00834
00835 if (!found)
00836 {
00837 V_wxString::iterator it = legacy_names_.begin();
00838 V_wxString::iterator end = legacy_names_.end();
00839 for (; it != end; ++it)
00840 {
00841 found = true;
00842 found &= config->Read( prefix_ + *it + wxT("R"), &r, c.r_ );
00843 found &= config->Read( prefix_ + *it + wxT("G"), &g, c.g_ );
00844 found &= config->Read( prefix_ + *it + wxT("B"), &b, c.b_ );
00845
00846 if (found)
00847 {
00848 break;
00849 }
00850 }
00851 }
00852
00853 set( Color( r, g, b ) );
00854 }
00855
00856 EnumProperty::EnumProperty( const std::string& name, const std::string& prefix, const CategoryPropertyWPtr& parent, const Getter& getter, const Setter& setter )
00857 : Property<int>( name, prefix, parent, getter, setter )
00858 , choices_(new wxPGChoices)
00859 {
00860 choices_->EnsureData();
00861 }
00862
00863 void EnumProperty::addOption( const std::string& name, int value )
00864 {
00865 boost::mutex::scoped_lock lock(mutex_);
00866 choices_->Add(wxString::FromAscii( name.c_str() ), value);
00867 changed();
00868 }
00869
00870 void EnumProperty::clear ()
00871 {
00872 boost::mutex::scoped_lock lock(mutex_);
00873 choices_->Clear();
00874 changed();
00875 }
00876
00877 void EnumProperty::writeToGrid()
00878 {
00879 boost::mutex::scoped_lock lock(mutex_);
00880
00881 if (isSelected())
00882 {
00883 changed();
00884 return;
00885 }
00886
00887 if ( !property_ )
00888 {
00889 property_ = grid_->AppendIn( getCategoryPGProperty(parent_), new wxEnumProperty( name_, prefix_ + name_ ) );
00890 wxPGChoices choices = choices_->Copy();
00891 grid_->SetPropertyChoices(property_, choices);
00892
00893 if ( !hasSetter() )
00894 {
00895 grid_->DisableProperty( property_ );
00896 }
00897 }
00898 else
00899 {
00900 wxPGChoices choices = choices_->Copy();
00901 grid_->SetPropertyChoices(property_, choices);
00902 grid_->SetPropertyValue(property_, (long)get());
00903 }
00904
00905 setPropertyHelpText(property_, help_text_);
00906 }
00907
00908 void EnumProperty::readFromGrid()
00909 {
00910 wxVariant var = property_->GetValue();
00911 set( var.GetLong() );
00912 }
00913
00914 void EnumProperty::saveToConfig( wxConfigBase* config )
00915 {
00916 config->Write( prefix_ + name_, (int)get() );
00917 }
00918
00919 void EnumProperty::loadFromConfig( wxConfigBase* config )
00920 {
00921 long val = 0xffffffff;
00922 if (!config->Read( prefix_ + name_, &val, get() ))
00923 {
00924 V_wxString::iterator it = legacy_names_.begin();
00925 V_wxString::iterator end = legacy_names_.end();
00926 for (; it != end; ++it)
00927 {
00928 if (config->Read( prefix_ + *it, &val, get() ))
00929 {
00930 break;
00931 }
00932 }
00933 }
00934
00935 set( val );
00936 }
00937
00938 EditEnumProperty::EditEnumProperty( const std::string& name, const std::string& prefix, const CategoryPropertyWPtr& parent, const Getter& getter, const Setter& setter )
00939 : Property<std::string>( name, prefix, parent, getter, setter )
00940 , choices_(new wxPGChoices)
00941 , ee_property_(0)
00942 {
00943 choices_->EnsureData();
00944 }
00945
00946 void EditEnumProperty::addOption( const std::string& name )
00947 {
00948 boost::mutex::scoped_lock lock(mutex_);
00949 choices_->Add(wxString::FromAscii( name.c_str() ));
00950 changed();
00951 }
00952
00953 void EditEnumProperty::setOptionCallback(const EditEnumOptionCallback& cb)
00954 {
00955 option_cb_ = cb;
00956 if (ee_property_)
00957 {
00958 ee_property_->setOptionCallback(cb);
00959 }
00960
00961 changed();
00962 }
00963
00964 void EditEnumProperty::clear ()
00965 {
00966 boost::mutex::scoped_lock lock(mutex_);
00967 choices_->Clear();
00968 changed();
00969 }
00970
00971 void EditEnumProperty::writeToGrid()
00972 {
00973 boost::mutex::scoped_lock lock(mutex_);
00974
00975 if (isSelected())
00976 {
00977 changed();
00978 return;
00979 }
00980
00981 if ( !property_ )
00982 {
00983 ee_property_ = new EditEnumPGProperty(name_, prefix_ + name_);
00984 property_ = grid_->AppendIn( getCategoryPGProperty(parent_), ee_property_ );
00985 wxPGChoices choices = choices_->Copy();
00986 grid_->SetPropertyChoices(property_, choices);
00987
00988 if ( !hasSetter() )
00989 {
00990 grid_->DisableProperty( property_ );
00991 }
00992 }
00993 else
00994 {
00995 wxPGChoices choices = choices_->Copy();
00996 grid_->SetPropertyChoices(property_, choices);
00997 grid_->SetPropertyValue(property_, wxString::FromAscii( get().c_str() ));
00998 }
00999
01000 setPropertyHelpText(property_, help_text_);
01001 }
01002
01003 void EditEnumProperty::readFromGrid()
01004 {
01005 wxString str = property_->GetValueString();
01006 set( (const char*)str.mb_str() );
01007 }
01008
01009 void EditEnumProperty::saveToConfig( wxConfigBase* config )
01010 {
01011 config->Write( prefix_ + name_, wxString::FromAscii( get().c_str() ) );
01012 }
01013
01014 void EditEnumProperty::loadFromConfig( wxConfigBase* config )
01015 {
01016 wxString val;
01017 if (!config->Read( prefix_ + name_, &val, wxString::FromAscii( get().c_str() ) ))
01018 {
01019 V_wxString::iterator it = legacy_names_.begin();
01020 V_wxString::iterator end = legacy_names_.end();
01021 for (; it != end; ++it)
01022 {
01023 if (config->Read( prefix_ + *it, &val, wxString::FromAscii( get().c_str() ) ))
01024 {
01025 break;
01026 }
01027 }
01028 }
01029
01030 set( (const char*)val.mb_str() );
01031 }
01032
01033 void TFFrameProperty::writeToGrid()
01034 {
01035 if ( !property_ )
01036 {
01037 tf_frame_property_ = new TFFramePGProperty( name_, prefix_ + name_, wxString::FromAscii( get().c_str() ) );
01038 property_ = grid_->AppendIn( getCategoryPGProperty(parent_), tf_frame_property_ );
01039
01040 if ( !hasSetter() )
01041 {
01042 grid_->DisableProperty( property_ );
01043 }
01044 }
01045 else
01046 {
01047 grid_->SetPropertyValue(property_, wxString::FromAscii( get().c_str() ));
01048 }
01049
01050 setPropertyHelpText(property_, help_text_);
01051 }
01052
01053 void CategoryProperty::setLabel( const std::string& label )
01054 {
01055 label_ = wxString::FromAscii(label.c_str());
01056
01057 if (grid_)
01058 {
01059 grid_->SetPropertyLabel( property_, wxString::FromAscii( label.c_str() ) );
01060
01061 wxPGCell* cell = property_->GetCell( 0 );
01062 if ( cell )
01063 {
01064
01065 }
01066 }
01067 }
01068
01069 void CategoryProperty::expand()
01070 {
01071 if (property_)
01072 {
01073 grid_->Expand( property_ );
01074 }
01075 }
01076
01077 void CategoryProperty::collapse()
01078 {
01079 if (property_)
01080 {
01081 grid_->Collapse( property_ );
01082 }
01083 }
01084
01085 void CategoryProperty::writeToGrid()
01086 {
01087 if ( !property_ )
01088 {
01089 if ( parent_.lock() )
01090 {
01091 if (checkbox_)
01092 {
01093 property_ = grid_->AppendIn( getCategoryPGProperty(parent_), new wxBoolProperty( label_, prefix_ + name_, get() ) );
01094 property_->SetAttribute( wxPG_BOOL_USE_CHECKBOX, true );
01095 }
01096 else
01097 {
01098 property_ = grid_->AppendIn( getCategoryPGProperty(parent_), new wxPropertyCategory( label_, prefix_ + name_ ) );
01099 }
01100 }
01101 else
01102 {
01103 if (checkbox_)
01104 {
01105 property_ = grid_->AppendIn( grid_->GetRoot(), new wxBoolProperty( label_, prefix_ + name_, get() ) );
01106 property_->SetAttribute( wxPG_BOOL_USE_CHECKBOX, true );
01107 }
01108 else
01109 {
01110 property_ = grid_->AppendIn( grid_->GetRoot(), new wxPropertyCategory( name_, prefix_ + name_ ) );
01111 }
01112 }
01113 }
01114 else
01115 {
01116 if (checkbox_)
01117 {
01118 grid_->SetPropertyValue(property_, get());
01119 }
01120 }
01121
01122 setPropertyHelpText(property_, help_text_);
01123 }
01124
01125 void CategoryProperty::readFromGrid()
01126 {
01127 if (checkbox_)
01128 {
01129 wxVariant var = property_->GetValue();
01130 set( var.GetBool() );
01131 }
01132 }
01133
01134 void CategoryProperty::saveToConfig( wxConfigBase* config )
01135 {
01136 if (checkbox_)
01137 {
01138 config->Write( prefix_ + name_, (int)get() );
01139 }
01140 }
01141
01142 void CategoryProperty::loadFromConfig( wxConfigBase* config )
01143 {
01144 if (checkbox_)
01145 {
01146 bool val;
01147 if (!config->Read( prefix_ + name_, &val, get() ))
01148 {
01149 V_wxString::iterator it = legacy_names_.begin();
01150 V_wxString::iterator end = legacy_names_.end();
01151 for (; it != end; ++it)
01152 {
01153 if (config->Read( prefix_ + *it, &val, get() ))
01154 {
01155 break;
01156 }
01157 }
01158 }
01159
01160 set( val );
01161 }
01162 }
01163
01164 void CategoryProperty::setToError()
01165 {
01166 Property<bool>::setToError();
01167
01168 if (checkbox_)
01169 {
01170
01171 }
01172 }
01173
01174 void CategoryProperty::setToWarn()
01175 {
01176 Property<bool>::setToWarn();
01177
01178 if (checkbox_)
01179 {
01180
01181 }
01182 }
01183
01184 void CategoryProperty::setToOK()
01185 {
01186 if (grid_)
01187 {
01188 setPropertyToColors(property_, grid_->GetCaptionForegroundColour(), grid_->GetCaptionBackgroundColour(), 0);
01189 wxPGCell* cell = property_->GetCell(0);
01190 wxFont font = grid_->GetFont();
01191 font.SetWeight(wxBOLD);
01192 cell->SetFont(font);
01193
01194 }
01195 }
01196
01197 void CategoryProperty::setToDisabled()
01198 {
01199 Property<bool>::setToDisabled();
01200 if (checkbox_)
01201 {
01202
01203 }
01204 }
01205
01206 Vector3Property::~Vector3Property()
01207 {
01208 if (composed_parent_)
01209 {
01210 grid_->DeleteProperty( composed_parent_ );
01211 }
01212 }
01213
01214 void Vector3Property::setPrefix(const std::string& prefix)
01215 {
01216 prefix_ = wxString::FromAscii(prefix.c_str());
01217
01218 if (composed_parent_)
01219 {
01220 wxString composed_name = name_ + wxT("Composed");
01221 composed_parent_->SetName(prefix_ + composed_name);
01222 x_->SetName(prefix_ + name_ + wxT("X"));
01223 y_->SetName(prefix_ + name_ + wxT("Y"));
01224 z_->SetName(prefix_ + name_ + wxT("Z"));
01225 }
01226 }
01227
01228 void Vector3Property::writeToGrid()
01229 {
01230 if ( !composed_parent_ )
01231 {
01232 Ogre::Vector3 v = get();
01233
01234 wxString composed_name = name_ + wxT("Composed");
01235 composed_parent_ = grid_->AppendIn( getCategoryPGProperty(parent_), new wxStringProperty( name_, prefix_ + composed_name, wxT("<composed>")) );
01236 composed_parent_->SetClientData( this );
01237
01238 x_ = grid_->AppendIn( composed_parent_, new wxFloatProperty( wxT("X"), prefix_ + name_ + wxT("X"), v.x ) );
01239 y_ = grid_->AppendIn( composed_parent_, new wxFloatProperty( wxT("Y"), prefix_ + name_ + wxT("Y"), v.y ) );
01240 z_ = grid_->AppendIn( composed_parent_, new wxFloatProperty( wxT("Z"), prefix_ + name_ + wxT("Z"), v.z ) );
01241
01242 if ( !hasSetter() )
01243 {
01244 grid_->DisableProperty( composed_parent_ );
01245 grid_->DisableProperty( x_ );
01246 grid_->DisableProperty( y_ );
01247 grid_->DisableProperty( z_ );
01248 }
01249
01250 grid_->Collapse( composed_parent_ );
01251 }
01252 else
01253 {
01254 Ogre::Vector3 v = get();
01255 grid_->SetPropertyValue(x_, v.x);
01256 grid_->SetPropertyValue(y_, v.y);
01257 grid_->SetPropertyValue(z_, v.z);
01258 }
01259
01260 setPropertyHelpText(composed_parent_, help_text_);
01261 setPropertyHelpText(x_, help_text_);
01262 setPropertyHelpText(y_, help_text_);
01263 setPropertyHelpText(z_, help_text_);
01264 }
01265
01266 void Vector3Property::readFromGrid()
01267 {
01268 set( Ogre::Vector3( x_->GetValue().GetDouble(), y_->GetValue().GetDouble(), z_->GetValue().GetDouble() ) );
01269 }
01270
01271 void Vector3Property::saveToConfig( wxConfigBase* config )
01272 {
01273 Ogre::Vector3 v = get();
01274
01275 config->Write( prefix_ + name_ + wxT("X"), v.x );
01276 config->Write( prefix_ + name_ + wxT("Y"), v.y );
01277 config->Write( prefix_ + name_ + wxT("Z"), v.z );
01278 }
01279
01280 void Vector3Property::loadFromConfig( wxConfigBase* config )
01281 {
01282 Ogre::Vector3 v = get();
01283 double x, y, z;
01284 bool found = true;
01285 found &= config->Read( prefix_ + name_ + wxT("X"), &x, v.x );
01286 found &= config->Read( prefix_ + name_ + wxT("Y"), &y, v.y );
01287 found &= config->Read( prefix_ + name_ + wxT("Z"), &z, v.z );
01288
01289 if (!found)
01290 {
01291 V_wxString::iterator it = legacy_names_.begin();
01292 V_wxString::iterator end = legacy_names_.end();
01293 for (; it != end; ++it)
01294 {
01295 found = true;
01296 found &= config->Read( prefix_ + *it + wxT("X"), &x, v.x );
01297 found &= config->Read( prefix_ + *it + wxT("Y"), &y, v.y );
01298 found &= config->Read( prefix_ + *it + wxT("Z"), &z, v.z );
01299
01300 if (found)
01301 {
01302 break;
01303 }
01304 }
01305 }
01306
01307 set( Ogre::Vector3( x, y, z ) );
01308 }
01309
01310 void Vector3Property::setPGClientData()
01311 {
01312 if (composed_parent_)
01313 {
01314 composed_parent_->SetClientData(this);
01315 x_->SetClientData( this );
01316 y_->SetClientData( this );
01317 z_->SetClientData( this );
01318 }
01319 }
01320
01321 void Vector3Property::reset()
01322 {
01323 Property<Ogre::Vector3>::reset();
01324
01325 composed_parent_ = 0;
01326 x_ = 0;
01327 y_ = 0;
01328 z_ = 0;
01329 }
01330
01331 void Vector3Property::hide()
01332 {
01333 if (composed_parent_)
01334 {
01335 composed_parent_->Hide(true);
01336 }
01337 }
01338
01339 void Vector3Property::show()
01340 {
01341 if (composed_parent_)
01342 {
01343 composed_parent_->Hide(false);
01344 }
01345 }
01346
01347 QuaternionProperty::~QuaternionProperty()
01348 {
01349 if (composed_parent_)
01350 {
01351 grid_->DeleteProperty( composed_parent_ );
01352 }
01353 }
01354
01355 void QuaternionProperty::setPrefix(const std::string& prefix)
01356 {
01357 prefix_ = wxString::FromAscii(prefix.c_str());
01358
01359 if (composed_parent_)
01360 {
01361 wxString composed_name = name_ + wxT("Composed");
01362 composed_parent_->SetName(prefix_ + composed_name);
01363 x_->SetName(prefix_ + name_ + wxT("X"));
01364 y_->SetName(prefix_ + name_ + wxT("Y"));
01365 z_->SetName(prefix_ + name_ + wxT("Z"));
01366 w_->SetName(prefix_ + name_ + wxT("W"));
01367 }
01368 }
01369
01370 void QuaternionProperty::writeToGrid()
01371 {
01372 if ( !composed_parent_ )
01373 {
01374 Ogre::Quaternion q = get();
01375
01376 wxString composed_name = name_ + wxT("Composed");
01377 composed_parent_ = grid_->AppendIn( getCategoryPGProperty(parent_), new wxStringProperty( name_, prefix_ + composed_name, wxT("<composed>")) );
01378 composed_parent_->SetClientData( this );
01379
01380 x_ = grid_->AppendIn( composed_parent_, new wxFloatProperty( wxT("X"), prefix_ + name_ + wxT("X"), q.x ) );
01381 y_ = grid_->AppendIn( composed_parent_, new wxFloatProperty( wxT("Y"), prefix_ + name_ + wxT("Y"), q.y ) );
01382 z_ = grid_->AppendIn( composed_parent_, new wxFloatProperty( wxT("Z"), prefix_ + name_ + wxT("Z"), q.z ) );
01383 w_ = grid_->AppendIn( composed_parent_, new wxFloatProperty( wxT("W"), prefix_ + name_ + wxT("W"), q.z ) );
01384
01385 if ( !hasSetter() )
01386 {
01387 grid_->DisableProperty( composed_parent_ );
01388 grid_->DisableProperty( x_ );
01389 grid_->DisableProperty( y_ );
01390 grid_->DisableProperty( z_ );
01391 grid_->DisableProperty( w_ );
01392 }
01393
01394 grid_->Collapse( composed_parent_ );
01395 }
01396 else
01397 {
01398 Ogre::Quaternion q = get();
01399 grid_->SetPropertyValue(x_, q.x);
01400 grid_->SetPropertyValue(y_, q.y);
01401 grid_->SetPropertyValue(z_, q.z);
01402 grid_->SetPropertyValue(w_, q.w);
01403 }
01404
01405 setPropertyHelpText(composed_parent_, help_text_);
01406 setPropertyHelpText(x_, help_text_);
01407 setPropertyHelpText(y_, help_text_);
01408 setPropertyHelpText(z_, help_text_);
01409 setPropertyHelpText(w_, help_text_);
01410 }
01411
01412 void QuaternionProperty::readFromGrid()
01413 {
01414 set( Ogre::Quaternion( x_->GetValue().GetDouble(), y_->GetValue().GetDouble(), z_->GetValue().GetDouble(), w_->GetValue().GetDouble() ) );
01415 }
01416
01417 void QuaternionProperty::saveToConfig( wxConfigBase* config )
01418 {
01419 Ogre::Quaternion q = get();
01420
01421 config->Write( prefix_ + name_ + wxT("X"), q.x );
01422 config->Write( prefix_ + name_ + wxT("Y"), q.y );
01423 config->Write( prefix_ + name_ + wxT("Z"), q.z );
01424 config->Write( prefix_ + name_ + wxT("W"), q.w );
01425 }
01426
01427 void QuaternionProperty::loadFromConfig( wxConfigBase* config )
01428 {
01429 Ogre::Quaternion q = get();
01430 double x, y, z, w;
01431 bool found = true;
01432 found &= config->Read( prefix_ + name_ + wxT("X"), &x, q.x );
01433 found &= config->Read( prefix_ + name_ + wxT("Y"), &y, q.y );
01434 found &= config->Read( prefix_ + name_ + wxT("Z"), &z, q.z );
01435 found &= config->Read( prefix_ + name_ + wxT("W"), &w, q.w );
01436
01437 if (!found)
01438 {
01439 V_wxString::iterator it = legacy_names_.begin();
01440 V_wxString::iterator end = legacy_names_.end();
01441 for (; it != end; ++it)
01442 {
01443 found = true;
01444 found &= config->Read( prefix_ + *it + wxT("X"), &x, q.x );
01445 found &= config->Read( prefix_ + *it + wxT("Y"), &y, q.y );
01446 found &= config->Read( prefix_ + *it + wxT("Z"), &z, q.z );
01447 found &= config->Read( prefix_ + *it + wxT("W"), &w, q.w );
01448
01449 if (found)
01450 {
01451 break;
01452 }
01453 }
01454 }
01455
01456 set( Ogre::Quaternion( x, y, z, w ) );
01457 }
01458
01459 void QuaternionProperty::setPGClientData()
01460 {
01461 if (composed_parent_)
01462 {
01463 composed_parent_->SetClientData(this);
01464 x_->SetClientData( this );
01465 y_->SetClientData( this );
01466 z_->SetClientData( this );
01467 w_->SetClientData( this );
01468 }
01469 }
01470
01471 void QuaternionProperty::reset()
01472 {
01473 Property<Ogre::Quaternion>::reset();
01474
01475 composed_parent_ = 0;
01476 x_ = 0;
01477 y_ = 0;
01478 z_ = 0;
01479 w_ = 0;
01480 }
01481
01482 void QuaternionProperty::hide()
01483 {
01484 if (composed_parent_)
01485 {
01486 composed_parent_->Hide(true);
01487 }
01488 }
01489
01490 void QuaternionProperty::show()
01491 {
01492 if (composed_parent_)
01493 {
01494 composed_parent_->Hide(false);
01495 }
01496 }
01497
01498 }