$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 "visualization_frame.h" 00031 #include "render_panel.h" 00032 #include "displays_panel.h" 00033 #include "views_panel.h" 00034 #include "time_panel.h" 00035 #include "selection_panel.h" 00036 #include "tool_properties_panel.h" 00037 #include "visualization_manager.h" 00038 #include "tools/tool.h" 00039 #include "plugin_manager_dialog.h" 00040 #include "splash_screen.h" 00041 #include "loading_dialog.h" 00042 00043 #include <ros/package.h> 00044 #include <ros/console.h> 00045 00046 #include <ogre_tools/initialization.h> 00047 00048 #include <wx/config.h> 00049 #include <wx/confbase.h> 00050 #include <wx/stdpaths.h> 00051 #include <wx/menu.h> 00052 #include <wx/toolbar.h> 00053 #include <wx/aui/aui.h> 00054 #include <wx/filedlg.h> 00055 #include <wx/artprov.h> 00056 00057 #include <boost/filesystem.hpp> 00058 #include <boost/bind.hpp> 00059 #include <boost/algorithm/string/split.hpp> 00060 #include <boost/algorithm/string/trim.hpp> 00061 00062 namespace fs = boost::filesystem; 00063 00064 #define CONFIG_WINDOW_X wxT("/Window/X") 00065 #define CONFIG_WINDOW_Y wxT("/Window/Y") 00066 #define CONFIG_WINDOW_WIDTH wxT("/Window/Width") 00067 #define CONFIG_WINDOW_HEIGHT wxT("/Window/Height") 00068 #define CONFIG_AUIMANAGER_PERSPECTIVE wxT("/AuiManagerPerspective") 00069 #define CONFIG_AUIMANAGER_PERSPECTIVE_VERSION wxT("/AuiManagerPerspectiveVersion") 00070 #define CONFIG_RECENT_CONFIGS wxT("/RecentConfigs") 00071 #define CONFIG_LAST_DIR wxT("/LastConfigDir") 00072 00073 #define CONFIG_EXTENSION "vcg" 00074 #define CONFIG_EXTENSION_WILDCARD "*."CONFIG_EXTENSION 00075 #define PERSPECTIVE_VERSION 2 00076 00077 #define RECENT_CONFIG_COUNT 10 00078 00079 namespace rviz 00080 { 00081 00082 namespace toolbar_items 00083 { 00084 enum ToolbarItem 00085 { 00086 Count, 00087 }; 00088 } 00089 typedef toolbar_items::ToolbarItem ToolbarItem; 00090 00091 VisualizationFrame::VisualizationFrame(wxWindow* parent) 00092 : wxFrame(parent, wxID_ANY, wxT("RViz"), wxDefaultPosition, wxSize(1024, 768), wxDEFAULT_FRAME_STYLE) 00093 , render_panel_(NULL) 00094 , displays_panel_(NULL) 00095 , views_panel_(NULL) 00096 , time_panel_(NULL) 00097 , selection_panel_(NULL) 00098 , tool_properties_panel_(NULL) 00099 , menubar_(NULL) 00100 , file_menu_(NULL) 00101 , recent_configs_menu_(NULL) 00102 , toolbar_(NULL) 00103 , aui_manager_(NULL) 00104 , manager_(NULL) 00105 { 00106 wxInitAllImageHandlers(); 00107 } 00108 00109 VisualizationFrame::~VisualizationFrame() 00110 { 00111 Disconnect(wxEVT_AUI_PANE_CLOSE, wxAuiManagerEventHandler(VisualizationFrame::onPaneClosed), NULL, this); 00112 #if !defined(__WXMAC__) 00113 if (toolbar_) 00114 { 00115 toolbar_->Disconnect( wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( VisualizationFrame::onToolClicked ), NULL, this ); 00116 } 00117 #endif 00118 00119 if (general_config_ && aui_manager_) 00120 { 00121 saveConfigs(); 00122 } 00123 00124 if (manager_) 00125 { 00126 manager_->removeAllDisplays(); 00127 } 00128 00129 if (aui_manager_) 00130 { 00131 aui_manager_->UnInit(); 00132 delete aui_manager_; 00133 } 00134 00135 if (render_panel_) 00136 { 00137 render_panel_->Destroy(); 00138 } 00139 delete manager_; 00140 } 00141 00142 void VisualizationFrame::onSplashLoadStatus(const std::string& status, SplashScreen* splash) 00143 { 00144 splash->setState(status); 00145 } 00146 00147 void VisualizationFrame::initialize(const std::string& display_config_file, 00148 const std::string& fixed_frame, const std::string& target_frame, const std::string& splash_path, 00149 bool verbose ) 00150 { 00151 initConfigs(); 00152 00153 wxPoint pos = GetPosition(); 00154 wxSize size = GetSize(); 00155 int width = size.GetWidth(); 00156 int height = size.GetHeight(); 00157 general_config_->Read(CONFIG_WINDOW_X, &pos.x, pos.x); 00158 general_config_->Read(CONFIG_WINDOW_Y, &pos.y, pos.y); 00159 general_config_->Read(CONFIG_WINDOW_WIDTH, &width, width); 00160 general_config_->Read(CONFIG_WINDOW_HEIGHT, &height, height); 00161 00162 { 00163 wxString str; 00164 if (general_config_->Read(CONFIG_RECENT_CONFIGS, &str)) 00165 { 00166 std::string recent = (const char*)str.char_str(); 00167 00168 boost::trim(recent); 00169 boost::split(recent_configs_, recent, boost::is_any_of (":"), boost::token_compress_on); 00170 } 00171 00172 if (general_config_->Read(CONFIG_LAST_DIR, &str)) 00173 { 00174 last_config_dir_ = (const char*)str.char_str(); 00175 } 00176 } 00177 00178 SetPosition(pos); 00179 SetSize(wxSize(width, height)); 00180 00181 package_path_ = ros::package::getPath("rviz"); 00182 00183 std::string final_splash_path = splash_path; 00184 00185 if ( splash_path.empty() ) 00186 { 00187 #if BOOST_FILESYSTEM_VERSION == 3 00188 final_splash_path = (fs::path(package_path_) / "images/splash.png").string(); 00189 #else 00190 final_splash_path = (fs::path(package_path_) / "images/splash.png").file_string(); 00191 #endif 00192 } 00193 wxImage splash_image; 00194 splash_image.LoadFile(wxString::FromAscii(final_splash_path.c_str())); 00195 splash_ = new SplashScreen(this, wxBitmap(splash_image)); 00196 splash_->Show(); 00197 splash_->setState("Initializing"); 00198 00199 if (!ros::isInitialized()) 00200 { 00201 int argc = 0; 00202 ros::init(argc, 0, "rviz", ros::init_options::AnonymousName); 00203 } 00204 00205 render_panel_ = new RenderPanel( this ); 00206 displays_panel_ = new DisplaysPanel( this ); 00207 views_panel_ = new ViewsPanel( this ); 00208 time_panel_ = new TimePanel( this ); 00209 selection_panel_ = new SelectionPanel( this ); 00210 tool_properties_panel_ = new ToolPropertiesPanel(this); 00211 00212 splash_->setState("Initializing OGRE resources"); 00213 ogre_tools::V_string paths; 00214 paths.push_back(package_path_ + "/ogre_media/textures"); 00215 ogre_tools::initializeResources( paths ); 00216 00217 #if !defined(__WXMAC__) 00218 toolbar_ = new wxToolBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_TEXT|wxTB_NOICONS|wxNO_BORDER|wxTB_HORIZONTAL); 00219 toolbar_->Connect( wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( VisualizationFrame::onToolClicked ), NULL, this ); 00220 #endif 00221 00222 aui_manager_ = new wxAuiManager(this); 00223 aui_manager_->AddPane(render_panel_, wxAuiPaneInfo().CenterPane().Name(wxT("Render"))); 00224 aui_manager_->AddPane(displays_panel_, wxAuiPaneInfo().Left().MinSize(270, -1).Name(wxT("Displays")).Caption(wxT("Displays"))); 00225 aui_manager_->AddPane(selection_panel_, wxAuiPaneInfo().Right().MinSize(270, -1).Name(wxT("Selection")).Caption(wxT("Selection"))); 00226 aui_manager_->AddPane(views_panel_, wxAuiPaneInfo().BestSize(230, 200).Right().Name(wxT("Views")).Caption(wxT("Views"))); 00227 aui_manager_->AddPane(tool_properties_panel_, wxAuiPaneInfo().BestSize(230, 200).Right().Name(wxT("Tool Properties")).Caption(wxT("Tool Properties"))); 00228 aui_manager_->AddPane(time_panel_, wxAuiPaneInfo().RightDockable(false).LeftDockable(false).Bottom().Name(wxT("Time")).Caption(wxT("Time"))); 00229 #if !defined(__WXMAC__) 00230 aui_manager_->AddPane(toolbar_, wxAuiPaneInfo().ToolbarPane().RightDockable(false).LeftDockable(false)/*.MinSize(-1, 40)*/.Top().Name(wxT("Tools")).Caption(wxT("Tools"))); 00231 #endif 00232 aui_manager_->Update(); 00233 00234 Connect(wxEVT_AUI_PANE_CLOSE, wxAuiManagerEventHandler(VisualizationFrame::onPaneClosed), NULL, this); 00235 00236 manager_ = new VisualizationManager(render_panel_, this); 00237 render_panel_->initialize(manager_->getSceneManager(), manager_); 00238 displays_panel_->initialize(manager_); 00239 views_panel_->initialize(manager_); 00240 time_panel_->initialize(manager_); 00241 selection_panel_->initialize(manager_); 00242 tool_properties_panel_->initialize(manager_); 00243 00244 manager_->getToolAddedSignal().connect( boost::bind( &VisualizationFrame::onToolAdded, this, _1 ) ); 00245 manager_->getToolChangedSignal().connect( boost::bind( &VisualizationFrame::onToolChanged, this, _1 ) ); 00246 00247 manager_->initialize( StatusCallback(), verbose ); 00248 manager_->loadGeneralConfig(general_config_, boost::bind(&VisualizationFrame::onSplashLoadStatus, this, _1, splash_)); 00249 00250 bool display_config_valid = !display_config_file.empty(); 00251 if (display_config_valid && !fs::exists(display_config_file)) 00252 { 00253 ROS_ERROR("File [%s] does not exist", display_config_file.c_str()); 00254 display_config_valid = false; 00255 } 00256 00257 if (!display_config_valid) 00258 { 00259 manager_->loadDisplayConfig(display_config_, boost::bind(&VisualizationFrame::onSplashLoadStatus, this, _1, splash_)); 00260 } 00261 else 00262 { 00263 boost::shared_ptr<wxFileConfig> config(new wxFileConfig(wxT("standalone_visualizer"), wxEmptyString, wxEmptyString, wxString::FromAscii(display_config_file.c_str()), wxCONFIG_USE_GLOBAL_FILE|wxCONFIG_USE_RELATIVE_PATH)); 00264 manager_->loadDisplayConfig(config, boost::bind(&VisualizationFrame::onSplashLoadStatus, this, _1, splash_)); 00265 } 00266 00267 if (!fixed_frame.empty()) 00268 { 00269 manager_->setFixedFrame(fixed_frame); 00270 } 00271 00272 if (!target_frame.empty()) 00273 { 00274 manager_->setTargetFrame(target_frame); 00275 } 00276 00277 splash_->setState("Loading perspective"); 00278 00279 wxString auimanager_perspective; 00280 long version = 0; 00281 if (general_config_->Read(CONFIG_AUIMANAGER_PERSPECTIVE_VERSION, &version)) 00282 { 00283 if (version >= PERSPECTIVE_VERSION) 00284 { 00285 if (general_config_->Read(CONFIG_AUIMANAGER_PERSPECTIVE, &auimanager_perspective)) 00286 { 00287 wxAuiPaneInfoArray panes_backup = aui_manager_->GetAllPanes(); 00288 aui_manager_->LoadPerspective(auimanager_perspective); 00289 //wxAUI overwrites the 'visible' state when loading the 00290 //perspective, which we don't want for panes that were created 00291 //by displays (those without a close button) so we have to 00292 //restore it 00293 wxAuiPaneInfoArray& panes = aui_manager_->GetAllPanes(); 00294 if (panes.GetCount() == panes_backup.GetCount()) 00295 { 00296 for (uint32_t i = 0; i < panes.GetCount(); ++i) 00297 { 00298 if (!panes.Item(i).HasCloseButton()) 00299 { 00300 panes.Item(i).Show( panes_backup.Item(i).IsShown() ); 00301 } 00302 } 00303 } 00304 else 00305 { 00306 ROS_INFO("Number of panes changed during aui_manager_->LoadPerspective(). Can't update visibility of display windows."); 00307 } 00308 aui_manager_->Update(); 00309 } 00310 } 00311 else 00312 { 00313 ROS_INFO("Perspective version has changed (version [%d] is less than version [%d], resetting windows", (int)version, PERSPECTIVE_VERSION); 00314 } 00315 } 00316 00317 initMenus(); 00318 updateRecentConfigMenu(); 00319 if (display_config_valid) 00320 { 00321 markRecentConfig(display_config_file); 00322 } 00323 00324 splash_->Destroy(); 00325 splash_ = 0; 00326 00327 manager_->startUpdate(); 00328 } 00329 00330 void VisualizationFrame::initConfigs() 00331 { 00332 config_dir_ = (const char*)wxStandardPaths::Get().GetUserConfigDir().fn_str(); 00333 #if BOOST_FILESYSTEM_VERSION == 3 00334 std::string old_dir = (fs::path(config_dir_) / ".standalone_visualizer").string(); 00335 config_dir_ = (fs::path(config_dir_) / ".rviz").string(); 00336 general_config_file_ = (fs::path(config_dir_) / "config").string(); 00337 display_config_file_ = (fs::path(config_dir_) / "display_config").string(); 00338 #else 00339 std::string old_dir = (fs::path(config_dir_) / ".standalone_visualizer").file_string(); 00340 config_dir_ = (fs::path(config_dir_) / ".rviz").file_string(); 00341 general_config_file_ = (fs::path(config_dir_) / "config").file_string(); 00342 display_config_file_ = (fs::path(config_dir_) / "display_config").file_string(); 00343 #endif 00344 00345 if (fs::exists(old_dir) && !fs::exists(config_dir_)) 00346 { 00347 ROS_INFO("Migrating old config directory to new location ([%s] to [%s])", old_dir.c_str(), config_dir_.c_str()); 00348 fs::rename(old_dir, config_dir_); 00349 } 00350 00351 if (fs::is_regular_file(config_dir_)) 00352 { 00353 ROS_INFO("Migrating old config file to new location ([%s] to [%s])", config_dir_.c_str(), general_config_file_.c_str()); 00354 std::string backup_file = config_dir_ + "bak"; 00355 00356 fs::rename(config_dir_, backup_file); 00357 fs::create_directory(config_dir_); 00358 fs::rename(backup_file, general_config_file_); 00359 } 00360 else if (!fs::exists(config_dir_)) 00361 { 00362 fs::create_directory(config_dir_); 00363 } 00364 00365 if (fs::exists(general_config_file_) && !fs::exists(display_config_file_)) 00366 { 00367 ROS_INFO("Creating display config from general config"); 00368 fs::copy_file(general_config_file_, display_config_file_); 00369 } 00370 00371 ROS_INFO("Loading general config from [%s]", general_config_file_.c_str()); 00372 general_config_.reset(new wxFileConfig(wxT("standalone_visualizer"), wxEmptyString, wxString::FromAscii(general_config_file_.c_str()))); 00373 ROS_INFO("Loading display config from [%s]", display_config_file_.c_str()); 00374 display_config_.reset(new wxFileConfig(wxT("standalone_visualizer"), wxEmptyString, wxString::FromAscii(display_config_file_.c_str()))); 00375 } 00376 00377 void VisualizationFrame::initMenus() 00378 { 00379 menubar_ = new wxMenuBar(); 00380 file_menu_ = new wxMenu(wxT("")); 00381 wxMenuItem* item = file_menu_->Append(wxID_OPEN, wxT("&Open Config\tCtrl-O")); 00382 Connect(item->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VisualizationFrame::onOpen), NULL, this); 00383 item = file_menu_->Append(wxID_SAVE, wxT("&Save Config\tCtrl-S")); 00384 Connect(item->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VisualizationFrame::onSave), NULL, this); 00385 00386 recent_configs_menu_ = new wxMenu(wxT("")); 00387 file_menu_->Append(wxID_ANY, wxT("&Recent Configs"), recent_configs_menu_); 00388 00389 file_menu_->AppendSeparator(); 00390 item = file_menu_->Append(wxID_EXIT, wxT("&Quit")); 00391 Connect(item->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VisualizationFrame::onClose), NULL, this); 00392 00393 menubar_->Append(file_menu_, wxT("&File")); 00394 00395 view_menu_ = new wxMenu(wxT("")); 00396 wxAuiPaneInfoArray& panes = aui_manager_->GetAllPanes(); 00397 for (uint32_t i = 0; i < panes.GetCount(); ++i) 00398 { 00399 wxAuiPaneInfo& pane = panes.Item(i); 00400 00401 if (pane.HasCloseButton()) 00402 { 00403 item = view_menu_->AppendCheckItem(pane.window->GetId(), pane.caption); 00404 item->Check(pane.IsShown()); 00405 Connect(item->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VisualizationFrame::onViewMenuItemSelected), NULL, this); 00406 } 00407 } 00408 00409 menubar_->Append(view_menu_, wxT("&View")); 00410 00411 plugins_menu_ = new wxMenu(wxT("")); 00412 item = plugins_menu_->Append(wxID_ANY, wxT("&Manage...")); 00413 Connect(item->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VisualizationFrame::onManagePlugins), NULL, this); 00414 menubar_->Append(plugins_menu_, wxT("&Plugins")); 00415 00416 help_menu_ = new wxMenu(wxT("")); 00417 item = help_menu_->Append(wxID_ANY, wxT("&Wiki")); 00418 Connect(item->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VisualizationFrame::onHelpWiki), NULL, this); 00419 menubar_->Append(help_menu_, wxT("&Help")); 00420 00421 SetMenuBar(menubar_); 00422 } 00423 00424 void VisualizationFrame::updateRecentConfigMenu() 00425 { 00426 // wtf. no Clear method 00427 while (recent_configs_menu_->GetMenuItemCount() > 0) 00428 { 00429 wxMenuItem* item = recent_configs_menu_->FindItemByPosition(0); 00430 recent_configs_menu_->Remove(item); 00431 } 00432 00433 D_string::iterator it = recent_configs_.begin(); 00434 D_string::iterator end = recent_configs_.end(); 00435 for (; it != end; ++it) 00436 { 00437 const std::string& path = *it; 00438 wxMenuItem* item = recent_configs_menu_->Append(wxID_ANY, wxString::FromAscii(path.c_str())); 00439 Connect(item->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(VisualizationFrame::onRecentConfigSelected), NULL, this); 00440 } 00441 } 00442 00443 void VisualizationFrame::markRecentConfig(const std::string& path) 00444 { 00445 D_string::iterator it = std::find(recent_configs_.begin(), recent_configs_.end(), path); 00446 if (it != recent_configs_.end()) 00447 { 00448 recent_configs_.erase(it); 00449 } 00450 00451 recent_configs_.push_front(path); 00452 00453 if (recent_configs_.size() > RECENT_CONFIG_COUNT) 00454 { 00455 recent_configs_.pop_back(); 00456 } 00457 00458 updateRecentConfigMenu(); 00459 } 00460 00461 void VisualizationFrame::loadDisplayConfig(const std::string& path) 00462 { 00463 if (!fs::exists(path)) 00464 { 00465 wxString message = wxString::FromAscii(path.c_str()) + wxT(" does not exist!"); 00466 wxMessageBox(message, wxT("Config Does Not Exist"), wxOK|wxICON_ERROR, this); 00467 return; 00468 } 00469 00470 manager_->removeAllDisplays(); 00471 00472 LoadingDialog dialog(this); 00473 dialog.Show(); 00474 00475 boost::shared_ptr<wxFileConfig> config(new wxFileConfig(wxT("standalone_visualizer"), wxEmptyString, wxEmptyString, wxString::FromAscii(path.c_str()), wxCONFIG_USE_GLOBAL_FILE)); 00476 manager_->loadDisplayConfig(config, boost::bind(&LoadingDialog::setState, &dialog, _1)); 00477 00478 markRecentConfig(path); 00479 } 00480 00481 void VisualizationFrame::saveConfigs() 00482 { 00483 ROS_INFO("Saving general config to [%s]", general_config_file_.c_str()); 00484 general_config_->DeleteAll(); 00485 wxPoint pos = GetPosition(); 00486 wxSize size = GetSize(); 00487 general_config_->Write(CONFIG_WINDOW_X, pos.x); 00488 general_config_->Write(CONFIG_WINDOW_Y, pos.y); 00489 general_config_->Write(CONFIG_WINDOW_WIDTH, size.GetWidth()); 00490 general_config_->Write(CONFIG_WINDOW_HEIGHT, size.GetHeight()); 00491 00492 general_config_->Write(CONFIG_AUIMANAGER_PERSPECTIVE, aui_manager_->SavePerspective()); 00493 general_config_->Write(CONFIG_AUIMANAGER_PERSPECTIVE_VERSION, PERSPECTIVE_VERSION); 00494 00495 { 00496 std::stringstream ss; 00497 D_string::iterator it = recent_configs_.begin(); 00498 D_string::iterator end = recent_configs_.end(); 00499 for (; it != end; ++it) 00500 { 00501 if (it != recent_configs_.begin()) 00502 { 00503 ss << ":"; 00504 } 00505 ss << *it; 00506 } 00507 00508 wxString str = wxString::FromAscii(ss.str().c_str()); 00509 general_config_->Write(CONFIG_RECENT_CONFIGS, str); 00510 } 00511 00512 general_config_->Write(CONFIG_LAST_DIR, wxString::FromAscii(last_config_dir_.c_str())); 00513 00514 manager_->saveGeneralConfig(general_config_); 00515 general_config_->Flush(); 00516 00517 ROS_INFO("Saving display config to [%s]", display_config_file_.c_str()); 00518 display_config_->DeleteAll(); 00519 manager_->saveDisplayConfig(display_config_); 00520 display_config_->Flush(); 00521 } 00522 00523 void VisualizationFrame::onClose(wxCommandEvent& event) 00524 { 00525 Close(); 00526 } 00527 00528 void VisualizationFrame::onPaneClosed(wxAuiManagerEvent& event) 00529 { 00530 wxAuiPaneInfo* pane = event.GetPane(); 00531 wxWindow* window = pane->window; 00532 menubar_->Check(window->GetId(), false); 00533 00534 // In some situations a pane can be closed by the computer's window 00535 // manager. In that case we need this call to let the window know 00536 // it is being closed. 00537 window->Close(); 00538 } 00539 00540 void VisualizationFrame::onViewMenuItemSelected(wxCommandEvent& event) 00541 { 00542 wxAuiPaneInfoArray& panes = aui_manager_->GetAllPanes(); 00543 for (uint32_t i = 0; i < panes.GetCount(); ++i) 00544 { 00545 wxAuiPaneInfo& pane = panes.Item(i); 00546 00547 if (pane.window->GetId() == event.GetId()) 00548 { 00549 pane.Show(event.IsChecked()); 00550 00551 aui_manager_->Update(); 00552 00553 break; 00554 } 00555 } 00556 } 00557 00558 void VisualizationFrame::onOpen(wxCommandEvent& event) 00559 { 00560 wxString wxstr_file = wxFileSelector(wxT("Choose a file to open"), wxString::FromAscii(last_config_dir_.c_str()), wxEmptyString, 00561 wxT(CONFIG_EXTENSION), wxT(CONFIG_EXTENSION_WILDCARD), wxFD_OPEN|wxFD_FILE_MUST_EXIST, this); 00562 if (!wxstr_file.empty()) 00563 { 00564 std::string filename = (const char*)wxstr_file.fn_str(); 00565 loadDisplayConfig(filename); 00566 00567 last_config_dir_ = fs::path(filename).parent_path().string(); 00568 } 00569 } 00570 00571 void VisualizationFrame::onSave(wxCommandEvent& event) 00572 { 00573 wxString wxstr_file = wxFileSelector(wxT("Choose a file to save to"), wxString::FromAscii(last_config_dir_.c_str()), wxEmptyString, 00574 wxT(CONFIG_EXTENSION), wxT(CONFIG_EXTENSION_WILDCARD), wxFD_SAVE|wxFD_OVERWRITE_PROMPT, this); 00575 00576 if (!wxstr_file.empty()) 00577 { 00578 std::string filename = (const char*)wxstr_file.fn_str(); 00579 fs::path path(filename); 00580 if (path.extension() != "."CONFIG_EXTENSION) 00581 { 00582 filename += "."CONFIG_EXTENSION; 00583 } 00584 00585 boost::shared_ptr<wxFileConfig> config(new wxFileConfig(wxT("standalone_visualizer"), wxEmptyString, wxString::FromAscii(filename.c_str()))); 00586 config->DeleteAll(); 00587 00588 manager_->saveDisplayConfig(config); 00589 config->Flush(); 00590 00591 markRecentConfig(filename); 00592 00593 last_config_dir_ = fs::path(filename).parent_path().string(); 00594 } 00595 } 00596 00597 void VisualizationFrame::onRecentConfigSelected(wxCommandEvent& event) 00598 { 00599 wxString label = recent_configs_menu_->GetLabel(event.GetId()); 00600 if (!label.IsEmpty()) 00601 { 00602 std::string path = (const char*)label.char_str(); 00603 00604 // wx(gtk?) for some reason adds an extra underscore for each one it finds in a menu item 00605 size_t pos = path.find("__"); 00606 while (pos != std::string::npos) 00607 { 00608 path.erase(pos, 1); 00609 pos = path.find("__", pos + 1); 00610 } 00611 00612 loadDisplayConfig(path); 00613 } 00614 } 00615 00616 void VisualizationFrame::onToolAdded(Tool* tool) 00617 { 00618 #if !defined(__WXMAC__) 00619 char ascii_str[2] = { tool->getShortcutKey(), 0 }; 00620 wxString tooltip = wxString( wxT("Shortcut Key: ")) + wxString::FromAscii( ascii_str ); 00621 toolbar_->AddRadioTool( toolbar_->GetToolsCount(), wxString::FromAscii( tool->getName().c_str() ), wxNullBitmap, wxNullBitmap, tooltip ); 00622 00623 wxAuiPaneInfo& pane = aui_manager_->GetPane(toolbar_); 00624 pane.MinSize(toolbar_->GetSize()); 00625 aui_manager_->Update(); 00626 #endif 00627 } 00628 00629 void VisualizationFrame::onToolChanged(Tool* tool) 00630 { 00631 #if !defined(__WXMAC__) 00632 int count = toolbar_->GetToolsCount(); 00633 for ( int i = toolbar_items::Count; i < count; ++i ) 00634 { 00635 if ( manager_->getTool( i - toolbar_items::Count ) == tool ) 00636 { 00637 toolbar_->ToggleTool( i, true ); 00638 break; 00639 } 00640 } 00641 #endif 00642 } 00643 00644 void VisualizationFrame::onToolClicked( wxCommandEvent& event ) 00645 { 00646 int id = event.GetId(); 00647 if (id >= toolbar_items::Count) 00648 { 00649 Tool* tool = manager_->getTool( id - toolbar_items::Count ); 00650 00651 manager_->setCurrentTool( tool ); 00652 } 00653 else 00654 { 00655 switch (id) 00656 { 00657 default: 00658 break; 00659 } 00660 } 00661 } 00662 00663 void VisualizationFrame::onManagePlugins(wxCommandEvent& event) 00664 { 00665 PluginManagerDialog dialog(this, manager_->getPluginManager()); 00666 dialog.ShowModal(); 00667 } 00668 00669 void VisualizationFrame::onHelpWiki(wxCommandEvent& event) 00670 { 00671 wxLaunchDefaultBrowser(wxT("http://www.ros.org/wiki/rviz")); 00672 } 00673 00674 wxWindow* VisualizationFrame::getParentWindow() 00675 { 00676 return this; 00677 } 00678 00679 void VisualizationFrame::addPane(const std::string& name, wxWindow* panel) 00680 { 00681 aui_manager_->AddPane(panel, wxAuiPaneInfo().Float().BestSize(panel->GetSize()).Name(wxString::FromAscii(name.c_str())).Caption(wxString::FromAscii(name.c_str())).CloseButton(false).Show(false).Dockable(true).FloatingPosition(30,30)); 00682 aui_manager_->Update(); 00683 } 00684 00685 void VisualizationFrame::removePane(wxWindow* panel) 00686 { 00687 aui_manager_->DetachPane(panel); 00688 aui_manager_->Update(); 00689 } 00690 00691 void VisualizationFrame::showPane(wxWindow* panel) 00692 { 00693 wxAuiPaneInfo& pane = aui_manager_->GetPane(panel); 00694 00695 if (pane.IsOk()) 00696 { 00697 pane.Show(true); 00698 aui_manager_->Update(); 00699 } 00700 } 00701 00702 void VisualizationFrame::closePane(wxWindow* panel) 00703 { 00704 wxAuiPaneInfo& pane = aui_manager_->GetPane(panel); 00705 00706 if (pane.IsOk()) 00707 { 00708 pane.Show(false); 00709 aui_manager_->Update(); 00710 } 00711 } 00712 00713 }