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