pxmlw6n2f/Gazebo_Distributed_MPI/gazebo/gui/RenderWidget.cc

302 lines
8.2 KiB
C++

/*
* Copyright (C) 2012 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifdef _WIN32
// Ensure that Winsock2.h is included before Windows.h, which can get
// pulled in by anybody (e.g., Boost).
#include <Winsock2.h>
#endif
#include <boost/algorithm/string.hpp>
#include <boost/bind.hpp>
#include <iomanip>
#include "gazebo/rendering/RenderingIface.hh"
#include "gazebo/rendering/Scene.hh"
#include "gazebo/gui/GuiPlugin.hh"
#include "gazebo/gui/Actions.hh"
#include "gazebo/gui/GuiIface.hh"
#include "gazebo/gui/GLWidget.hh"
#include "gazebo/gui/GuiEvents.hh"
#include "gazebo/gui/TimePanel.hh"
#include "gazebo/gui/TopToolbar.hh"
#include "gazebo/gui/RenderWidget.hh"
using namespace gazebo;
using namespace gui;
/////////////////////////////////////////////////
RenderWidget::RenderWidget(QWidget *_parent)
: QWidget(_parent)
{
this->setObjectName("renderWidget");
QVBoxLayout *mainLayout = new QVBoxLayout;
this->mainFrame = new QFrame;
this->mainFrame->setFrameShape(QFrame::NoFrame);
this->mainFrame->show();
QVBoxLayout *frameLayout = new QVBoxLayout;
// Top toolbar
this->topToolbar = new TopToolbar();
// GLWigdet
this->glWidget = new GLWidget(this->mainFrame);
this->msgOverlayLabel = new QLabel(this->glWidget);
this->msgOverlayLabel->setStyleSheet(
"QLabel { background-color : white; color : gray; }");
this->msgOverlayLabel->setVisible(false);
QHBoxLayout *bottomPanelLayout = new QHBoxLayout;
this->timePanel = new TimePanel(this);
this->bottomFrame = new QFrame;
this->bottomFrame->setObjectName("renderBottomFrame");
this->bottomFrame->setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Minimum);
bottomPanelLayout->addWidget(this->timePanel, 0);
bottomPanelLayout->setSpacing(0);
bottomPanelLayout->setContentsMargins(0, 0, 0, 0);
this->bottomFrame->setLayout(bottomPanelLayout);
QFrame *render3DFrame = new QFrame;
render3DFrame->setObjectName("render3DFrame");
QVBoxLayout *render3DLayout = new QVBoxLayout;
render3DLayout->addWidget(this->topToolbar);
render3DLayout->addWidget(this->glWidget);
render3DLayout->setContentsMargins(0, 0, 0, 0);
render3DLayout->setSpacing(0);
render3DFrame->setLayout(render3DLayout);
this->splitter = new QSplitter(this);
this->splitter->addWidget(render3DFrame);
QList<int> sizes;
sizes.push_back(300);
this->splitter->setSizes(sizes);
this->splitter->setStretchFactor(0, 1);
this->splitter->setOrientation(Qt::Vertical);
frameLayout->addWidget(this->splitter);
frameLayout->addWidget(this->bottomFrame);
frameLayout->setContentsMargins(0, 0, 0, 0);
frameLayout->setSpacing(0);
this->mainFrame->setLayout(frameLayout);
this->mainFrame->layout()->setContentsMargins(0, 0, 0, 0);
mainLayout->addWidget(this->mainFrame);
this->setLayout(mainLayout);
this->layout()->setContentsMargins(0, 0, 0, 0);
this->connections.push_back(
gui::Events::ConnectFollow(
boost::bind(&RenderWidget::OnFollow, this, _1)));
// Load all GUI Plugins
std::string filenames = getINIProperty<std::string>(
"overlay_plugins.filenames", "");
std::vector<std::string> pluginFilenames;
// Split the colon separated libraries
boost::split(pluginFilenames, filenames, boost::is_any_of(":"));
// Load each plugin
for (std::vector<std::string>::iterator iter = pluginFilenames.begin();
iter != pluginFilenames.end(); ++iter)
{
// Make sure the string is not empty
if (!(*iter).empty())
{
// Try to create the plugin
gazebo::GUIPluginPtr plugin = gazebo::GUIPlugin::Create(*iter, *iter);
if (!plugin)
{
gzerr << "Unable to create gui overlay plugin with filename["
<< *iter << "]\n";
}
else
{
gzlog << "Loaded GUI plugin[" << *iter << "]\n";
// Set the plugin's parent and store the plugin
plugin->setParent(this->glWidget);
this->plugins.push_back(plugin);
}
}
}
}
/////////////////////////////////////////////////
RenderWidget::~RenderWidget()
{
delete this->glWidget;
this->glWidget = NULL;
delete this->topToolbar;
this->topToolbar = NULL;
// we created the scene here we are responsible for removing it.
rendering::remove_scene(gui::get_world());
}
/////////////////////////////////////////////////
void RenderWidget::InsertWidget(unsigned int _index, QWidget *_widget)
{
if (static_cast<int>(_index) <= this->splitter->count())
{
// set equal size for now. There should always be at least one widget
// (render3DFrame) in the splitter.
int childCount = this->splitter->count();
GZ_ASSERT(childCount > 0,
"RenderWidget splitter has no child widget");
QSize widgetSize = this->size();
int newSize = widgetSize.height() / (this->splitter->count()+1);
QList<int> newSizes;
for (int i = 0; i < childCount+1; ++i)
newSizes.append(newSize);
this->splitter->insertWidget(_index, _widget);
this->splitter->setSizes(newSizes);
this->splitter->setStretchFactor(_index, 1);
}
else
gzerr << "Unable to add widget, index out of range " << std::endl;
}
/////////////////////////////////////////////////
void RenderWidget::ShowTimePanel(bool _show)
{
if (_show)
this->bottomFrame->show();
else
this->bottomFrame->hide();
}
/////////////////////////////////////////////////
TimePanel *RenderWidget::GetTimePanel() const
{
return this->timePanel;
}
/////////////////////////////////////////////////
void RenderWidget::RemoveScene(const std::string &_name)
{
rendering::remove_scene(_name);
}
/////////////////////////////////////////////////
void RenderWidget::CreateScene(const std::string &_name)
{
rendering::create_scene(_name, true);
}
/////////////////////////////////////////////////
void RenderWidget::DisplayOverlayMsg(const std::string &_msg, int _duration)
{
std::string msg = this->baseOverlayMsg.empty() ? _msg
: this->baseOverlayMsg + "\n" + _msg;
this->msgOverlayLabel->setText(tr(msg.c_str()));
if (msg.empty())
{
this->msgOverlayLabel->setVisible(false);
return;
}
this->msgOverlayLabel->resize(
this->msgOverlayLabel->fontMetrics().width(tr(msg.c_str())),
this->msgOverlayLabel->fontMetrics().height());
this->msgOverlayLabel->setVisible(true);
if (_duration > 0)
QTimer::singleShot(_duration, this, SLOT(OnClearOverlayMsg()));
}
/////////////////////////////////////////////////
void RenderWidget::SetOverlaysVisible(const bool _visible)
{
for (auto const &plugin : this->plugins)
plugin->setVisible(_visible);
}
/////////////////////////////////////////////////
std::string RenderWidget::GetOverlayMsg() const
{
return this->msgOverlayLabel->text().toStdString();
}
/////////////////////////////////////////////////
void RenderWidget::ShowToolbar(const bool _show)
{
if (this->topToolbar)
{
if (_show)
{
this->topToolbar->show();
}
else
{
this->topToolbar->hide();
}
}
}
/////////////////////////////////////////////////
TopToolbar *RenderWidget::GetToolbar() const
{
return this->topToolbar;
}
/////////////////////////////////////////////////
void RenderWidget::OnClearOverlayMsg()
{
this->DisplayOverlayMsg("");
}
/////////////////////////////////////////////////
void RenderWidget::OnFollow(const std::string &_modelName)
{
if (_modelName.empty())
{
g_translateAct->setEnabled(true);
g_rotateAct->setEnabled(true);
}
else
{
g_translateAct->setEnabled(false);
g_rotateAct->setEnabled(false);
}
}
/////////////////////////////////////////////////
void RenderWidget::AddPlugin(GUIPluginPtr _plugin, sdf::ElementPtr _elem)
{
// Set the plugin's parent and store the plugin
_plugin->setParent(this->glWidget);
this->plugins.push_back(_plugin);
// Load the plugin.
_plugin->Load(_elem);
_plugin->show();
}