Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add link menu updates #1177

Merged
merged 7 commits into from
Nov 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions include/ignition/gazebo/gui/GuiEvents.hh
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ namespace events
/// \brief Constructor
/// \param[in] _tranformModeActive is the transform control mode active
public: explicit ModelEditorAddEntity(QString _entity, QString _type,
ignition::gazebo::Entity _parent) : QEvent(kType), entity(_entity),
type(_type), parent(_parent)
ignition::gazebo::Entity _parent, QString _uri) : QEvent(kType), entity(_entity),
type(_type), parent(_parent), uri(_uri)
{
}

Expand All @@ -176,6 +176,12 @@ namespace events
return this->entity;
}

/// \brief Get the URI, if any, associated with the entity to add
public: QString Uri() const
{
return this->uri;
}

/// \brief Get the entity type
public: QString EntityType() const
{
Expand All @@ -194,6 +200,7 @@ namespace events
private: QString entity;
private: QString type;
private: ignition::gazebo::Entity parent;
private: QString uri;
};

} // namespace events
Expand Down
31 changes: 29 additions & 2 deletions src/gui/plugins/component_inspector/ComponentInspector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <iostream>
#include <regex>
#include <ignition/common/Console.hh>
#include <ignition/common/MeshManager.hh>
#include <ignition/common/Profiler.hh>
#include <ignition/gui/Application.hh>
#include <ignition/gui/MainWindow.hh>
Expand Down Expand Up @@ -1022,17 +1023,43 @@ bool ComponentInspector::NestedModel() const
}

/////////////////////////////////////////////////
void ComponentInspector::OnAddEntity(QString _entity, QString _type)
void ComponentInspector::OnAddEntity(const QString &_entity,
const QString &_type)
{
// currently just assumes parent is the model
// todo(anyone) support adding visuals / collisions / sensors to links
ignition::gazebo::gui::events::ModelEditorAddEntity addEntityEvent(
_entity, _type, this->dataPtr->entity);
_entity, _type, this->dataPtr->entity, QString(""));
ignition::gui::App()->sendEvent(
ignition::gui::App()->findChild<ignition::gui::MainWindow *>(),
&addEntityEvent);
}

/////////////////////////////////////////////////
void ComponentInspector::OnLoadMesh(const QString &_entity,
const QString &_type, const QString &_mesh)
{
std::string meshStr = _mesh.toStdString();
if (QUrl(_mesh).isLocalFile())
{
// mesh to sdf model
common::rtrim(meshStr);

if (!common::MeshManager::Instance()->IsValidFilename(meshStr))
{
QString errTxt = QString::fromStdString("Invalid URI: " + meshStr +
"\nOnly mesh file types DAE, OBJ, and STL are supported.");
return;
}

ignition::gazebo::gui::events::ModelEditorAddEntity addEntityEvent(
_entity, _type, this->dataPtr->entity, QString(meshStr.c_str()));
ignition::gui::App()->sendEvent(
ignition::gui::App()->findChild<ignition::gui::MainWindow *>(),
&addEntityEvent);
}
}

// Register this plugin
IGNITION_ADD_PLUGIN(ignition::gazebo::ComponentInspector,
ignition::gui::Plugin)
10 changes: 9 additions & 1 deletion src/gui/plugins/component_inspector/ComponentInspector.hh
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,15 @@ namespace gazebo
/// \brief Callback in Qt thread when an entity is to be added
/// \param[in] _entity Entity to add, e.g. box, sphere, cylinder, etc
/// \param[in] _type Entity type, e.g. link, visual, collision, etc
public: Q_INVOKABLE void OnAddEntity(QString _entity, QString _type);
public: Q_INVOKABLE void OnAddEntity(const QString &_entity,
const QString &_type);

/// \brief Callback to insert a new entity
/// \param[in] _entity Entity to add, e.g. box, sphere, cylinder, etc
/// \param[in] _type Entity type, e.g. link, visual, collision, etc
/// \param[in] _mesh Mesh file to load.
public: Q_INVOKABLE void OnLoadMesh(const QString &_entity,
const QString &_type, const QString &_mesh);

/// \internal
/// \brief Pointer to private data.
Expand Down
251 changes: 147 additions & 104 deletions src/gui/plugins/component_inspector/ComponentInspector.qml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import QtQuick 2.9
import QtQuick.Controls 1.4
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.1
import QtQuick.Dialogs 1.0
import QtQuick.Layouts 1.3
import QtQuick.Controls.Styles 1.4
import IgnGazebo 1.0 as IgnGazebo
Expand Down Expand Up @@ -125,6 +126,20 @@ Rectangle {
_heading);
}

// The component for a menu section header
Component {
id: menuSectionHeading
Rectangle {
height: childrenRect.height

Text {
text: sectionText
font.pointSize: 10
padding: 5
}
}
}

Rectangle {
id: header
height: lockButton.height
Expand Down Expand Up @@ -218,6 +233,138 @@ Rectangle {
onClicked: {
addLinkMenu.open()
}

FileDialog {
id: loadFileDialog
title: "Load mesh"
folder: shortcuts.home
nameFilters: [ "Collada files (*.dae)", "(*.stl)", "(*.obj)" ]
selectMultiple: false
selectExisting: true
onAccepted: {
ComponentInspector.OnLoadMesh("mesh", "link", fileUrl)
}
}

Menu {
id: addLinkMenu

Item {
Layout.fillWidth: true
height: childrenRect.height
Loader {
property string sectionText: "Link"
sourceComponent: menuSectionHeading
}
}

MenuItem {
id: boxLink
text: "Box"
onClicked: {
ComponentInspector.OnAddEntity("box", "link");
addLinkMenu.close()
}
}

MenuItem {
id: capsuleLink
text: "Capsule"
onClicked: {
ComponentInspector.OnAddEntity("capsule", "link");
addLinkMenu.close()
}
}

MenuItem {
id: cylinderLink
text: "Cylinder"
onClicked: {
ComponentInspector.OnAddEntity("cylinder", "link");
}
}

MenuItem {
id: ellipsoidLink
text: "Ellipsoid"
onClicked: {
ComponentInspector.OnAddEntity("ellipsoid", "link");
}
}

MenuItem {
id: emptyLink
text: "Empty"
onClicked: {
ComponentInspector.OnAddEntity("empty", "link");
}
}

MenuItem {
id: meshLink
text: "Mesh"
onClicked: {
loadFileDialog.open()
}
}

MenuItem {
id: sphereLink
text: "Sphere"
onClicked: {
ComponentInspector.OnAddEntity("sphere", "link");
}
}

MenuSeparator {
padding: 0
topPadding: 12
bottomPadding: 12
contentItem: Rectangle {
implicitWidth: 200
implicitHeight: 1
color: "#1E000000"
}
}

Item {
Layout.fillWidth: true
height: childrenRect.height
Loader {
property string sectionText: "Light"
sourceComponent: menuSectionHeading
}
}

MenuItem {
id: directionalLink
text: "Directional"
onClicked: {
ComponentInspector.OnAddEntity("directional", "light");
addLinkMenu.close()
}
}

MenuItem {
id: pointLink
text: "Point"
onClicked: {
ComponentInspector.OnAddEntity("point", "light");
addLinkMenu.close()
}
}

MenuItem {
id: spotLink
text: "Spot"
onClicked: {
ComponentInspector.OnAddEntity("spot", "light");
addLinkMenu.close()
}
}

// \todo(anyone) Add joints
}
}

Label {
Expand All @@ -231,110 +378,6 @@ Rectangle {
}
}

ListModel {
id: linkItems
ListElement {
text: "Box"
type: "Link"
}
ListElement {
text: "Cylinder"
type: "Link"
}
ListElement {
text: "Empty"
type: "Link"
}
ListElement {
text: "Sphere"
type: "Link"
}
ListElement {
text: "Capsule"
type: "Link"
}
ListElement {
text: "Ellipsoid"
type: "Link"
}
ListElement {
text: "Directional"
type: "Light"
}
ListElement {
text: "Spot"
type: "Light"
}
ListElement {
text: "Point"
type: "Light"
}

// \todo Uncomment the following items once they are supported
// ListElement {
// text: "Mesh"
// type: "Link"
// }
// ListElement {
// text: "Ball"
// type: "Joint"
// }
// ListElement {
// text: "Continuous"
// type: "Joint"
// }
// ListElement {
// text: "Fixed"
// type: "Joint"
// }
// ListElement {
// text: "Prismatic"
// type: "Joint"
// }
// ListElement {
// text: "Revolute"
// type: "Joint"
// }
// ListElement {
// text: "Universal"
// type: "Joint"
// }
}
// The delegate for each section header
Component {
id: sectionHeading
Rectangle {
height: childrenRect.height

Text {
text: section
font.pointSize: 10
padding: 5
}
}
}

Menu {
id: addLinkMenu
ListView {
id: addLinkMenuListView
height: addLinkMenu.height
delegate: ItemDelegate {
width: parent.width
text: model.text
highlighted: ListView.isCurrentItem
onClicked: {
ComponentInspector.OnAddEntity(model.text, "link");
addLinkMenu.close()
}
}
model: linkItems
section.property: "type"
section.criteria: ViewSection.FullString
section.delegate: sectionHeading
}
}


ListView {
anchors.top: header.bottom
Expand Down
4 changes: 2 additions & 2 deletions src/gui/plugins/entity_tree/EntityTree.hh
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ namespace gazebo
public: Q_INVOKABLE void OnInsertEntity(const QString &_type);

/// \brief Callback to insert a new entity
/// \param[in] _type Type of entity to insert
public: Q_INVOKABLE void OnLoadMesh(const QString &_type);
/// \param[in] _file Mesh file to create a model from.
public: Q_INVOKABLE void OnLoadMesh(const QString &_mesh);

// Documentation inherited
protected: bool eventFilter(QObject *_obj, QEvent *_event) override;
Expand Down
Loading