$search
00001 /* 00002 * Copyright (c) 2008, 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 "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 /* START_WX-2.9_COMPAT_CODE 00074 This code is related to ticket: https://code.ros.org/trac/ros-pkg/ticket/5157 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 /* END_WX-2.9_COMPAT_CODE */ 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 // Update the top level status here so that it can be used immediately 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 // Status hasn't changed, return 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 // Update the top level status here so that it can be used immediately 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 // Update the top level status here so that it can be used immediately 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 //setPropertyToWarn(status.property); 00388 break; 00389 case status_levels::Error: 00390 setPropertyToColors(status.property, ERROR_COLOR, *wxWHITE); 00391 //setPropertyToError(status.property); 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 //setPropertyToOK(top_property_); 00430 label = name_ + wxT(": OK"); 00431 break; 00432 case status_levels::Warn: 00433 setPropertyToColors(top_property_, WARN_COLOR, *wxWHITE); 00434 //setPropertyToWarn(top_property_); 00435 label = name_ + wxT(": Warning"); 00436 break; 00437 case status_levels::Error: 00438 setPropertyToColors(top_property_, ERROR_COLOR, *wxWHITE); 00439 //setPropertyToError(top_property_); 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 /* START_WX-2.9_COMPAT_CODE 00452 This code is related to ticket: https://code.ros.org/trac/ros-pkg/ticket/5157 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 // The new API returns a reference not a pointer 00458 // and the library automatically creates a cell if one does not exists for you 00459 wxPGCell _cell = top_property_->GetCell( 0 ); 00460 wxPGCell* cell = &_cell; 00461 #endif 00462 if ( cell ) 00463 { 00464 //cell->SetText(label); 00465 } 00466 00467 #if wxMAJOR_VERSION == 2 and wxMINOR_VERSION == 8 // If wxWidgets 2.8.x 00468 grid_->Sort(top_property_); 00469 #else 00470 // This is the new way to sort a wxPropertyGrid 00471 grid_->Sort(); 00472 #endif 00473 /* END_WX-2.9_COMPAT_CODE */ 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 /* START_WX-2.9_COMPAT_CODE 00917 This code is related to ticket: https://code.ros.org/trac/ros-pkg/ticket/5157 00918 */ 00919 #if wxMAJOR_VERSION == 2 and wxMINOR_VERSION == 8 // If wxWidgets 2.8.x 00920 grid_->SetPropertyChoices(property_, choices); 00921 #else 00922 // This is the new way of doing this 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 // This is the new way of doing this 00938 property_->SetChoices(choices); 00939 #endif 00940 /* END_WX-2.9_COMPAT_CODE */ 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 /* START_WX-2.9_COMPAT_CODE 01026 This code is related to ticket: https://code.ros.org/trac/ros-pkg/ticket/5157 01027 */ 01028 #if wxMAJOR_VERSION == 2 and wxMINOR_VERSION == 8 // If wxWidgets 2.8.x 01029 grid_->SetPropertyChoices(property_, choices); 01030 #else 01031 // This is the new way of doing this 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 // This is the new way of doing this 01047 property_->SetChoices(choices); 01048 #endif 01049 /* END_WX-2.9_COMPAT_CODE */ 01050 grid_->SetPropertyValue(property_, wxString::FromAscii( get().c_str() )); 01051 } 01052 01053 setPropertyHelpText(property_, help_text_); 01054 } 01055 01056 void EditEnumProperty::readFromGrid() 01057 { 01058 /* START_WX-2.9_COMPAT_CODE 01059 This code is related to ticket: https://code.ros.org/trac/ros-pkg/ticket/5157 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 /* END_WX-2.9_COMPAT_CODE */ 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 /* START_WX-2.9_COMPAT_CODE 01123 This code is related to ticket: https://code.ros.org/trac/ros-pkg/ticket/5157 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 //cell->SetText( wxString::FromAscii( label.c_str() ) ); 01130 } 01131 #else 01132 wxPGCell _cell = property_->GetCell( 0 ); 01133 wxPGCell* cell = &_cell; 01134 if ( cell ) 01135 { 01136 //cell->SetText( wxString::FromAscii( label.c_str() ) ); 01137 } 01138 #endif 01139 /* END_WX-2.9_COMPAT_CODE */ 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 //setPropertyToError(property_, 1); 01245 } 01246 } 01247 01248 void CategoryProperty::setToWarn() 01249 { 01250 Property<bool>::setToWarn(); 01251 01252 if (checkbox_) 01253 { 01254 //setPropertyToWarn(property_, 1); 01255 } 01256 } 01257 01258 void CategoryProperty::setToOK() 01259 { 01260 if (grid_) 01261 { 01262 setPropertyToColors(property_, grid_->GetCaptionForegroundColour(), grid_->GetCaptionBackgroundColour(), 0); 01263 /* START_WX-2.9_COMPAT_CODE 01264 This code is related to ticket: https://code.ros.org/trac/ros-pkg/ticket/5157 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 /* END_WX-2.9_COMPAT_CODE */ 01276 //setPropertyToColors(property_, grid_->GetCaptionForegroundColour(), grid_->GetCaptionBackgroundColour(), 1); 01277 } 01278 } 01279 01280 void CategoryProperty::setToDisabled() 01281 { 01282 Property<bool>::setToDisabled(); 01283 if (checkbox_) 01284 { 01285 //setPropertyToDisabled(property_, 1); 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 }