pxmlw6n2f/Gazebo_Distributed_TCP/gazebo/gui/building/BuildingEditorPalette.cc

509 lines
17 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.
*
* Brick-wall, Window and Door designed by Juan Pablo Bravo from the
* thenounproject.com
* Stairs designed by Brian Oppenlander from the thenounproject.com
*/
#include <boost/bind.hpp>
#include "gazebo/gui/building/BuildingEditorPalettePrivate.hh"
#include "gazebo/gui/building/BuildingEditorPalette.hh"
#include "gazebo/gui/building/BuildingEditorEvents.hh"
#include "gazebo/gui/building/ImportImageDialog.hh"
using namespace gazebo;
using namespace gui;
/////////////////////////////////////////////////
BuildingEditorPalette::BuildingEditorPalette(QWidget *_parent)
: QWidget(_parent), dataPtr(new BuildingEditorPalettePrivate)
{
this->setObjectName("buildingEditorPalette");
this->dataPtr->buildingDefaultName = "Untitled";
this->dataPtr->currentMode = std::string();
QVBoxLayout *mainLayout = new QVBoxLayout;
// Model name layout
QHBoxLayout *modelNameLayout = new QHBoxLayout;
QLabel *modelLabel = new QLabel(tr("Model Name: "));
this->dataPtr->modelNameEdit = new QLineEdit();
this->dataPtr->modelNameEdit->setText(
tr(this->dataPtr->buildingDefaultName.c_str()));
modelNameLayout->addWidget(modelLabel);
modelNameLayout->addWidget(this->dataPtr->modelNameEdit);
connect(this->dataPtr->modelNameEdit, SIGNAL(textChanged(QString)), this,
SLOT(OnNameChanged(QString)));
// Brushes (button group)
this->dataPtr->brushes = new QButtonGroup();
connect(this->dataPtr->brushes, SIGNAL(buttonClicked(int)),
this, SLOT(OnBrush(int)));
QSize toolButtonSize(100, 100);
QSize iconSize(65, 65);
// Walls label
QLabel *wallsLabel = new QLabel(tr(
"<font size=4 color='white'>Create Walls</font>"));
// Wall button
QToolButton *wallButton = new QToolButton(this);
wallButton->setFixedSize(toolButtonSize);
wallButton->setCheckable(true);
wallButton->setChecked(false);
wallButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
wallButton->setIcon(QPixmap(":/images/wall.svg"));
wallButton->setText("Wall");
wallButton->setIconSize(QSize(iconSize));
wallButton->setToolTip("Hold Shift to override snapping");
this->dataPtr->brushIdToModeMap["wall"] =
this->dataPtr->brushes->buttons().size();
this->dataPtr->brushes->addButton(wallButton,
this->dataPtr->brushes->buttons().size());
// Features label
QLabel *featuresLabel = new QLabel(tr(
"<font size=4 color='white'>Add Features</font>"));
// Window button
QToolButton *windowButton = new QToolButton(this);
windowButton->setFixedSize(toolButtonSize);
windowButton->setCheckable(true);
windowButton->setChecked(false);
windowButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
windowButton->setIcon(QPixmap(":/images/window.svg"));
windowButton->setText("Window");
windowButton->setIconSize(QSize(iconSize));
this->dataPtr->brushIdToModeMap["window"] =
this->dataPtr->brushes->buttons().size();
this->dataPtr->brushes->addButton(windowButton,
this->dataPtr->brushes->buttons().size());
// Door button
QToolButton *doorButton = new QToolButton(this);
doorButton->setFixedSize(toolButtonSize);
doorButton->setCheckable(true);
doorButton->setChecked(false);
doorButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
doorButton->setIcon(QPixmap(":/images/door.svg"));
doorButton->setText("Door");
doorButton->setIconSize(QSize(iconSize));
this->dataPtr->brushIdToModeMap["door"] =
this->dataPtr->brushes->buttons().size();
this->dataPtr->brushes->addButton(doorButton,
this->dataPtr->brushes->buttons().size());
// Stairs button
QToolButton *stairsButton = new QToolButton(this);
stairsButton->setFixedSize(toolButtonSize);
stairsButton->setCheckable(true);
stairsButton->setChecked(false);
stairsButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
stairsButton->setIcon(QPixmap(":/images/stairs.svg"));
stairsButton->setText("Stairs");
stairsButton->setIconSize(QSize(iconSize));
this->dataPtr->brushIdToModeMap["stairs"] =
this->dataPtr->brushes->buttons().size();
this->dataPtr->brushes->addButton(stairsButton,
this->dataPtr->brushes->buttons().size());
// Features layout
QGridLayout *featuresLayout = new QGridLayout;
featuresLayout->addWidget(windowButton, 0, 0);
featuresLayout->addWidget(doorButton, 0, 1);
featuresLayout->addWidget(stairsButton, 1, 0);
// Colors
QLabel *colorsLabel = new QLabel(tr(
"<font size=4 color='white'>Add Color</font>"));
QGridLayout *colorsLayout = new QGridLayout;
this->dataPtr->colorList.push_back(QColor(255, 255, 255, 255));
this->dataPtr->colorList.push_back(QColor(194, 169, 160, 255));
this->dataPtr->colorList.push_back(QColor(235, 206, 157, 255));
this->dataPtr->colorList.push_back(QColor(254, 121, 5, 255));
this->dataPtr->colorList.push_back(QColor(255, 195, 78, 255));
this->dataPtr->colorList.push_back(QColor(111, 203, 172, 255));
for (unsigned int i = 0; i < this->dataPtr->colorList.size(); ++i)
{
QToolButton *colorButton = new QToolButton(this);
colorButton->setFixedSize(40, 40);
colorButton->setCheckable(true);
colorButton->setChecked(false);
colorButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
QPixmap colorIcon(30, 30);
colorIcon.fill(this->dataPtr->colorList.at(i));
colorButton->setIcon(colorIcon);
std::ostringstream colorStr;
colorStr << "color_" << i;
this->dataPtr->lastDefaultColor = colorStr.str();
this->dataPtr->brushIdToModeMap[this->dataPtr->lastDefaultColor] =
this->dataPtr->brushes->buttons().size();
this->dataPtr->brushes->addButton(colorButton,
this->dataPtr->brushes->buttons().size());
colorsLayout->addWidget(colorButton, 0, i);
}
this->dataPtr->customColorButton = new QPushButton("More");
this->dataPtr->customColorButton->setCheckable(true);
this->dataPtr->customColorButton->setChecked(false);
colorsLayout->addWidget(this->dataPtr->customColorButton, 1, 4, 1, 2);
this->dataPtr->brushIdToModeMap["color_custom"] =
this->dataPtr->brushes->buttons().size();
this->dataPtr->brushes->addButton(this->dataPtr->customColorButton,
this->dataPtr->brushes->buttons().size());
this->dataPtr->customColorDialog = new QColorDialog(Qt::green, this);
this->dataPtr->customColorDialog->setWindowModality(Qt::NonModal);
connect(this->dataPtr->customColorDialog,
SIGNAL(currentColorChanged(const QColor)),
this, SLOT(OnCustomColor(const QColor)));
connect(this->dataPtr->customColorDialog, SIGNAL(rejected()), this,
SLOT(CancelDrawModes()));
// Textures
QLabel *texturesLabel = new QLabel(tr(
"<font size=4 color='white'>Add Texture</font>"));
QGridLayout *texturesLayout = new QGridLayout;
std::vector<QString> textureButtonTextList;
this->dataPtr->textureList.push_back(":wood.jpg");
textureButtonTextList.push_back("Wood");
this->dataPtr->textureList.push_back(":tiles.jpg");
textureButtonTextList.push_back("Tiles");
this->dataPtr->textureList.push_back(":bricks.png");
textureButtonTextList.push_back("Bricks");
for (unsigned int i = 0; i < this->dataPtr->textureList.size(); ++i)
{
QToolButton *textureButton = new QToolButton(this);
textureButton->setFixedSize(70, 70);
textureButton->setCheckable(true);
textureButton->setChecked(false);
textureButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
textureButton->setIcon(QPixmap(this->dataPtr->textureList[i]).scaled(
QSize(90, 90), Qt::IgnoreAspectRatio));
textureButton->setText(textureButtonTextList[i]);
textureButton->setIconSize(QSize(40, 40));
std::ostringstream textureStr;
textureStr << "texture_" << i;
this->dataPtr->lastDefaultTexture = textureStr.str();
this->dataPtr->brushIdToModeMap[this->dataPtr->lastDefaultTexture] =
this->dataPtr->brushes->buttons().size();
this->dataPtr->brushes->addButton(textureButton,
this->dataPtr->brushes->buttons().size());
texturesLayout->addWidget(textureButton, 0, i);
}
// Import button
QPushButton *importImageButton = new QPushButton(tr("Import"),
this);
importImageButton->setCheckable(true);
importImageButton->setChecked(false);
importImageButton->setToolTip(tr(
"Import an existing floor plan to use as a guide"));
this->dataPtr->brushIdToModeMap["image"] =
this->dataPtr->brushes->buttons().size();
this->dataPtr->brushes->addButton(importImageButton,
this->dataPtr->brushes->buttons().size());
QHBoxLayout *buttonsLayout = new QHBoxLayout;
buttonsLayout->addWidget(importImageButton);
buttonsLayout->setAlignment(Qt::AlignHCenter);
buttonsLayout->setContentsMargins(30, 11, 30, 11);
// Main layout
mainLayout->addLayout(modelNameLayout);
mainLayout->addItem(new QSpacerItem(10, 20, QSizePolicy::Expanding,
QSizePolicy::Minimum));
mainLayout->addWidget(wallsLabel);
mainLayout->addWidget(wallButton);
mainLayout->addWidget(featuresLabel);
mainLayout->addLayout(featuresLayout);
mainLayout->addWidget(colorsLabel);
mainLayout->addLayout(colorsLayout);
mainLayout->addWidget(texturesLabel);
mainLayout->addLayout(texturesLayout);
mainLayout->addItem(new QSpacerItem(10, 20, QSizePolicy::Expanding,
QSizePolicy::Minimum));
mainLayout->addLayout(buttonsLayout);
mainLayout->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
// Scroll area
auto scrollWidget = new QWidget();
scrollWidget->setObjectName("buildingEditorPaletteScroll");
scrollWidget->setLayout(mainLayout);
scrollWidget->setMinimumWidth(200);
auto scrollArea = new QScrollArea;
scrollArea->setWidget(scrollWidget);
scrollArea->setWidgetResizable(true);
auto scrollLayout = new QVBoxLayout();
scrollLayout->addWidget(scrollArea);
this->setLayout(scrollLayout);
// Connections
this->dataPtr->connections.push_back(
gui::editor::Events::ConnectSaveBuildingModel(
boost::bind(&BuildingEditorPalette::OnSaveModel, this, _1)));
this->dataPtr->connections.push_back(
gui::editor::Events::ConnectNewBuildingModel(
boost::bind(&BuildingEditorPalette::OnNewModel, this)));
this->dataPtr->connections.push_back(
gui::editor::Events::ConnectCreateBuildingEditorItem(
boost::bind(&BuildingEditorPalette::OnCreateEditorItem, this, _1)));
}
/////////////////////////////////////////////////
BuildingEditorPalette::~BuildingEditorPalette()
{
delete this->dataPtr;
this->dataPtr = NULL;
}
/////////////////////////////////////////////////
std::string BuildingEditorPalette::GetModelName() const
{
return this->dataPtr->modelNameEdit->text().toStdString();
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnBrush(int _buttonId)
{
if (_buttonId == this->dataPtr->brushIdToModeMap["wall"])
{
this->OnDrawWall();
}
else if (_buttonId == this->dataPtr->brushIdToModeMap["window"])
{
this->OnAddWindow();
}
else if (_buttonId == this->dataPtr->brushIdToModeMap["door"])
{
this->OnAddDoor();
}
else if (_buttonId == this->dataPtr->brushIdToModeMap["stairs"])
{
this->OnAddStair();
}
else if (_buttonId >= this->dataPtr->brushIdToModeMap["color_0"] &&
_buttonId <= this->dataPtr->brushIdToModeMap[
this->dataPtr->lastDefaultColor])
{
this->OnDefaultColor(_buttonId -
this->dataPtr->brushIdToModeMap["color_0"]);
}
else if (_buttonId == this->dataPtr->brushIdToModeMap["color_custom"])
{
this->OnCustomColorDialog();
}
else if (_buttonId >= this->dataPtr->brushIdToModeMap["texture_0"] &&
_buttonId <= this->dataPtr->brushIdToModeMap[
this->dataPtr->lastDefaultTexture])
{
this->OnTexture(_buttonId - this->dataPtr->brushIdToModeMap["texture_0"]);
}
else if (_buttonId == this->dataPtr->brushIdToModeMap["image"])
{
this->OnImportImage();
}
else
{
gzerr << "Requested brush doesn't exist." << std::endl;
}
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnDrawWall()
{
if (this->dataPtr->currentMode != "wall")
gui::editor::Events::createBuildingEditorItem("wall");
else
this->CancelDrawModes();
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnAddWindow()
{
if (this->dataPtr->currentMode != "window")
gui::editor::Events::createBuildingEditorItem("window");
else
this->CancelDrawModes();
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnAddDoor()
{
if (this->dataPtr->currentMode != "door")
gui::editor::Events::createBuildingEditorItem("door");
else
this->CancelDrawModes();
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnImportImage()
{
if (this->dataPtr->currentMode != "image")
gui::editor::Events::createBuildingEditorItem("image");
else
this->CancelDrawModes();
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnAddStair()
{
if (this->dataPtr->currentMode != "stairs")
gui::editor::Events::createBuildingEditorItem("stairs");
else
this->CancelDrawModes();
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnNewModel()
{
this->dataPtr->modelNameEdit->setText(
tr(this->dataPtr->buildingDefaultName.c_str()));
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnSaveModel(const std::string &_saveName)
{
this->dataPtr->modelNameEdit->setText(tr(_saveName.c_str()));
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnNameChanged(const QString &_name)
{
gui::editor::Events::buildingNameChanged(_name.toStdString());
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnCreateEditorItem(const std::string &_mode)
{
gui::editor::Events::colorSelected(QColor::Invalid);
gui::editor::Events::textureSelected(QString(""));
if (_mode.empty() || this->dataPtr->currentMode == _mode)
{
this->dataPtr->brushes->setExclusive(false);
if (this->dataPtr->brushes->checkedButton())
this->dataPtr->brushes->checkedButton()->setChecked(false);
this->dataPtr->brushes->setExclusive(true);
this->dataPtr->currentMode.clear();
}
else
{
this->dataPtr->currentMode = _mode;
}
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnDefaultColor(int _colorId)
{
std::ostringstream colorStr;
colorStr << "color_" << _colorId;
QColor color = this->dataPtr->colorList[_colorId];
if (this->dataPtr->currentMode != colorStr.str())
{
this->dataPtr->currentMode = colorStr.str();
this->OnColor(color);
}
else
{
this->CancelDrawModes();
}
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnCustomColorDialog()
{
this->CancelDrawModes();
this->dataPtr->customColorButton->setChecked(true);
this->dataPtr->customColorDialog->show();
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnCustomColor(const QColor _color)
{
this->dataPtr->customColorButton->setChecked(true);
if (_color.isValid())
{
this->dataPtr->currentMode = "color_custom";
this->OnColor(_color);
}
else
{
this->CancelDrawModes();
}
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnColor(QColor _color)
{
gui::editor::Events::colorSelected(_color);
QPixmap colorCursor(30, 30);
colorCursor.fill(_color);
QApplication::setOverrideCursor(QCursor(colorCursor));
}
/////////////////////////////////////////////////
void BuildingEditorPalette::OnTexture(int _textureId)
{
std::ostringstream textureStr;
textureStr << "texture_" << _textureId;
QString texture = this->dataPtr->textureList[_textureId];
if (this->dataPtr->currentMode != textureStr.str())
{
gui::editor::Events::textureSelected(texture);
this->dataPtr->currentMode = textureStr.str();
QPixmap textureCursor(this->dataPtr->textureList[_textureId]);
textureCursor = textureCursor.scaled(QSize(30, 30), Qt::IgnoreAspectRatio,
Qt::SmoothTransformation);
QApplication::setOverrideCursor(textureCursor);
}
else
{
this->CancelDrawModes();
}
}
/////////////////////////////////////////////////
void BuildingEditorPalette::mousePressEvent(QMouseEvent * /*_event*/)
{
this->CancelDrawModes();
}
/////////////////////////////////////////////////
void BuildingEditorPalette::CancelDrawModes()
{
gui::editor::Events::createBuildingEditorItem(std::string());
}
/////////////////////////////////////////////////
QColorDialog *BuildingEditorPalette::CustomColorDialog() const
{
return this->dataPtr->customColorDialog;
}