From 466f46c51d45a2cec0b89f0a107611218eedf76c Mon Sep 17 00:00:00 2001 From: hdallard <hdallard@laas.fr> Date: Thu, 12 May 2016 16:16:46 +0200 Subject: [PATCH] Move hpp-gui core code to gepetto-viewer-corba --- CMakeLists.txt | 45 ++ cmake-modules/FindPythonQt.cmake | 58 ++ include/gepetto/gui/bodytreewidget.hh | 73 +++ include/gepetto/gui/color-map.hh | 72 +++ include/gepetto/gui/config-dep.hh.in | 6 + .../gui/dialog/dialogloadenvironment.hh | 67 +++ include/gepetto/gui/dialog/dialogloadrobot.hh | 72 +++ .../gepetto/gui/dialog/pluginmanagerdialog.hh | 125 ++++ include/gepetto/gui/fwd.hh | 25 + include/gepetto/gui/ledindicator.hh | 34 ++ include/gepetto/gui/mainwindow.hh | 125 ++++ include/gepetto/gui/meta.hh | 33 ++ include/gepetto/gui/omniorb/omniorbthread.hh | 213 +++++++ include/gepetto/gui/omniorb/url.hh | 24 + include/gepetto/gui/osgwidget.hh | 123 ++++ include/gepetto/gui/pick-handler.hh | 52 ++ include/gepetto/gui/plugin-interface.hh | 117 ++++ include/gepetto/gui/pythonwidget.hh | 40 ++ include/gepetto/gui/safeapplication.hh | 23 + include/gepetto/gui/settings.hh | 75 +++ include/gepetto/gui/tree-item.hh | 65 +++ .../gui/ui/dialog_loadRobotFromFile.ui | 100 ++++ .../gepetto/gui/ui/dialogloadenvironment.ui | 285 +++++++++ include/gepetto/gui/ui/dialogloadrobot.ui | 301 ++++++++++ include/gepetto/gui/ui/mainwindow.ui | 545 ++++++++++++++++++ include/gepetto/gui/ui/pluginmanagerdialog.ui | 103 ++++ include/gepetto/gui/windows-manager.hh | 85 +++ res/floor.png | Bin 0 -> 3597 bytes res/gepetto.png | Bin 0 -> 151712 bytes res/images.qrc | 18 + res/pause.png | Bin 0 -> 1850 bytes res/play.png | Bin 0 -> 1806 bytes res/record.gif | Bin 0 -> 1232 bytes res/record.png | Bin 0 -> 2038 bytes res/refresh.png | Bin 0 -> 2061 bytes res/selection.png | Bin 0 -> 159 bytes res/stop.png | Bin 0 -> 1797 bytes res/zoom_fit.png | Bin 0 -> 1292 bytes src/gui/CMakeLists.txt | 118 ++++ src/gui/bodytreewidget.cc | 168 ++++++ src/gui/dialog/dialogloadenvironment.cc | 98 ++++ src/gui/dialog/dialogloadrobot.cc | 104 ++++ src/gui/dialog/pluginmanagerdialog.cc | 184 ++++++ src/gui/gepetto-gui.in | 7 + src/gui/ledindicator.cc | 40 ++ src/gui/main.cc.in | 91 +++ src/gui/mainwindow.cc | 421 ++++++++++++++ src/gui/omniorbthread.cc | 130 +++++ src/gui/osgwidget.cc | 364 ++++++++++++ src/gui/pick-handler.cc | 180 ++++++ src/gui/pythonwidget.cc | 59 ++ src/gui/safeapplication.cc | 42 ++ src/gui/settings.cc | 407 +++++++++++++ src/gui/tree-item.cc | 143 +++++ src/gui/windows-manager.cc | 35 ++ 55 files changed, 5495 insertions(+) create mode 100644 cmake-modules/FindPythonQt.cmake create mode 100644 include/gepetto/gui/bodytreewidget.hh create mode 100644 include/gepetto/gui/color-map.hh create mode 100644 include/gepetto/gui/config-dep.hh.in create mode 100644 include/gepetto/gui/dialog/dialogloadenvironment.hh create mode 100644 include/gepetto/gui/dialog/dialogloadrobot.hh create mode 100644 include/gepetto/gui/dialog/pluginmanagerdialog.hh create mode 100644 include/gepetto/gui/fwd.hh create mode 100644 include/gepetto/gui/ledindicator.hh create mode 100644 include/gepetto/gui/mainwindow.hh create mode 100644 include/gepetto/gui/meta.hh create mode 100644 include/gepetto/gui/omniorb/omniorbthread.hh create mode 100644 include/gepetto/gui/omniorb/url.hh create mode 100644 include/gepetto/gui/osgwidget.hh create mode 100644 include/gepetto/gui/pick-handler.hh create mode 100644 include/gepetto/gui/plugin-interface.hh create mode 100644 include/gepetto/gui/pythonwidget.hh create mode 100644 include/gepetto/gui/safeapplication.hh create mode 100644 include/gepetto/gui/settings.hh create mode 100644 include/gepetto/gui/tree-item.hh create mode 100644 include/gepetto/gui/ui/dialog_loadRobotFromFile.ui create mode 100644 include/gepetto/gui/ui/dialogloadenvironment.ui create mode 100644 include/gepetto/gui/ui/dialogloadrobot.ui create mode 100644 include/gepetto/gui/ui/mainwindow.ui create mode 100644 include/gepetto/gui/ui/pluginmanagerdialog.ui create mode 100644 include/gepetto/gui/windows-manager.hh create mode 100644 res/floor.png create mode 100644 res/gepetto.png create mode 100644 res/images.qrc create mode 100644 res/pause.png create mode 100644 res/play.png create mode 100644 res/record.gif create mode 100644 res/record.png create mode 100644 res/refresh.png create mode 100644 res/selection.png create mode 100644 res/stop.png create mode 100644 res/zoom_fit.png create mode 100644 src/gui/CMakeLists.txt create mode 100644 src/gui/bodytreewidget.cc create mode 100644 src/gui/dialog/dialogloadenvironment.cc create mode 100644 src/gui/dialog/dialogloadrobot.cc create mode 100644 src/gui/dialog/pluginmanagerdialog.cc create mode 100644 src/gui/gepetto-gui.in create mode 100644 src/gui/ledindicator.cc create mode 100644 src/gui/main.cc.in create mode 100644 src/gui/mainwindow.cc create mode 100644 src/gui/omniorbthread.cc create mode 100644 src/gui/osgwidget.cc create mode 100644 src/gui/pick-handler.cc create mode 100644 src/gui/pythonwidget.cc create mode 100644 src/gui/safeapplication.cc create mode 100644 src/gui/settings.cc create mode 100644 src/gui/tree-item.cc create mode 100644 src/gui/windows-manager.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index b1f3533..26e4b6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,52 @@ PKG_CONFIG_APPEND_LIBS(${PROJECT_NAME}) INCLUDE_DIRECTORIES(SYSTEM ${EIGEN3_INCLUDE_DIRS}) +SET (${PROJECT_NAME}_HEADERS_MOC + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/mainwindow.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/safeapplication.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/osgwidget.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/tree-item.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/bodytreewidget.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/ledindicator.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/plugin-interface.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/omniorb/omniorbthread.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/omniorb/url.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/dialog/dialogloadrobot.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/dialog/dialogloadenvironment.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/dialog/pluginmanagerdialog.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/pick-handler.hh + ) +SET (${PROJECT_NAME}_HEADERS_NO_MOC + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/fwd.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/meta.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/settings.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/windows-manager.hh + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/color-map.hh + ${CMAKE_BINARY_DIR}/include/gepetto/gui/config-dep.hh + ) + +SET(${PROJECT_NAME}_FORMS + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/ui/mainwindow.ui + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/ui/dialogloadrobot.ui + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/ui/dialogloadenvironment.ui + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/ui/pluginmanagerdialog.ui + ) + +SET(${PROJECT_NAME}_RESOURCES ${CMAKE_SOURCE_DIR}/res/images.qrc) + +SET(${PROJECT_NAME}_HEADERS + ${${PROJECT_NAME}_HEADERS} + ${${PROJECT_NAME}_HEADERS_MOC} + ${${PROJECT_NAME}_HEADERS_NO_MOC}) + +config_files( + include/gepetto/gui/config-dep.hh + src/gui/main.cc + src/gui/gepetto-gui + ) + ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(src/gui) ADD_SUBDIRECTORY(blender) ADD_SUBDIRECTORY(examples EXCLUDE_FROM_ALL) diff --git a/cmake-modules/FindPythonQt.cmake b/cmake-modules/FindPythonQt.cmake new file mode 100644 index 0000000..7192bc1 --- /dev/null +++ b/cmake-modules/FindPythonQt.cmake @@ -0,0 +1,58 @@ +# Find PythonQt +# +# Sets PYTHONQT_FOUND, PYTHONQT_INCLUDE_DIR, PYTHONQT_LIBRARY, PYTHONQT_QTALL_LIBRARY, PYTHONQT_LIBRARIES +# + +IF(NOT EXISTS "${PYTHONQT_INSTALL_DIR}") + FIND_PATH(PYTHONQT_INSTALL_DIR include/PythonQt/PythonQt.h + DOC "Directory where PythonQt was installed.") +ENDIF() +# XXX Since PythonQt 3.0 is not yet cmakeified, depending +# on how PythonQt is built, headers will not always be +# installed in "include/PythonQt". That is why "src" +# is added as an option. See [1] for more details. +# [1] https://github.com/commontk/CTK/pull/538#issuecomment-86106367 +FIND_PATH(PYTHONQT_INCLUDE_DIR PythonQt.h + PATHS "${PYTHONQT_INSTALL_DIR}/include/PythonQt" + DOC "Path to the PythonQt include directory") + +SET(PYTHONQT_LIBRARIES) + +MACRO(_SEARCH_FOR COMPONENT) + STRING(TOUPPER ${COMPONENT} _COMP_UPPERCASE) + FIND_LIBRARY(${_COMP_UPPERCASE}_LIBRARY + NAMES ${COMPONENT} + PATHS "${PYTHONQT_INSTALL_DIR}/lib" + DOC "The ${COMPONENT} library.") + IF(NOT ${${_COMP_UPPERCASE}_LIBRARY} STREQUAL "${_COMP_UPPERCASE}_LIBRARY-NOTFOUND") + SET(${COMPONENT}_FOUND TRUE) + ENDIF(NOT ${${_COMP_UPPERCASE}_LIBRARY} STREQUAL "${_COMP_UPPERCASE}_LIBRARY-NOTFOUND") + + MARK_AS_ADVANCED(${${_COMP_UPPERCASE}_LIBRARY}) + SET(PYTHONQT_LIBRARIES ${PYTHONQT_LIBRARIES} ${${_COMP_UPPERCASE}_LIBRARY}) +ENDMACRO(_SEARCH_FOR COMP) + +_SEARCH_FOR(PythonQt) + +FOREACH(_COMPONENT_SHORT ${PythonQt_FIND_COMPONENTS}) + SET(_COMPONENT "PythonQt_${_COMPONENT_SHORT}") + _SEARCH_FOR(${_COMPONENT}) +ENDFOREACH(_COMPONENT_SHORT ${PythonQt_FIND_COMPONENTS}) + +MARK_AS_ADVANCED(PYTHONQT_INSTALL_DIR) +MARK_AS_ADVANCED(PYTHONQT_INCLUDE_DIR) +MARK_AS_ADVANCED(PYTHONQT_LIBRARIES) + +# All upper case _FOUND variable is maintained for backwards compatibility. +SET(PythonQt_FOUND 0) +IF(PYTHONQT_INCLUDE_DIR AND PYTHONQT_LIBRARIES) + # Currently CMake'ified PythonQt only supports building against a python Release build. + ADD_DEFINITIONS(-DPYTHONQT_USE_RELEASE_PYTHON_FALLBACK) + SET(PythonQt_FOUND 1) +ENDIF() +SET(PYTHONQT_FOUND ${PythonQt_FOUND}) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonQt + REQUIRED_VARS PYTHONQT_LIBRARY PYTHONQT_INCLUDE_DIR + HANDLE_COMPONENTS) diff --git a/include/gepetto/gui/bodytreewidget.hh b/include/gepetto/gui/bodytreewidget.hh new file mode 100644 index 0000000..da5df3e --- /dev/null +++ b/include/gepetto/gui/bodytreewidget.hh @@ -0,0 +1,73 @@ +#ifndef GEPETTO_GUI_BODYTREEWIDGET_HH +#define GEPETTO_GUI_BODYTREEWIDGET_HH + +// This does not work because of qt meta-object compiler +#define GEPETTO_GUI_BODYTREE_DECL_FEATURE(func, ArgType) \ + public slots: \ + void func (ArgType arg) +#define GEPETTO_GUI_BODYTREE_IMPL_FEATURE(func, ArgType, CorbaType, WindowsManagerFunc) \ + void BodyTreeWidget::func (ArgType arg) { \ + WindowsManagerPtr_t wsm = MainWindow::instance()->osg(); \ + foreach (const QModelIndex& index, view_->selectionModel ()->selectedIndexes ()) { \ + const BodyTreeItem *item = dynamic_cast <const BodyTreeItem*> \ + (model_->itemFromIndex (index)); \ + if (item) wsm->WindowsManagerFunc (item->node()->getID().c_str(), \ + Traits<CorbaType>::from (arg).in()); \ + } \ + } + +#include <QWidget> +#include <QTreeView> +#include <QToolBox> +#include <QStandardItemModel> +#include <QVector3D> + +#include <gepetto/viewer/group-node.h> + +#include <gepetto/gui/fwd.hh> + +namespace gepetto { + namespace gui { + class BodyTreeWidget : public QWidget + { + Q_OBJECT + + public: + explicit BodyTreeWidget (QWidget* parent = NULL) + : QWidget (parent) + {} + + void init(QTreeView *view, QToolBox* toolBox); + + virtual ~BodyTreeWidget () {} + + void addBodyToTree (graphics::GroupNodePtr_t group); + void changeAlphaValue(const float& alpha); + + QTreeView* view (); + + public slots: + void selectBodyByName (const QString bodyName); + void selectBodyByName (const std::string& bodyName); + void reloadBodyTree (); + + protected slots: + void customContextMenu (const QPoint& pos); + + public slots: + void setTransparency(int value); + void setVisibilityMode (QString arg); + void setWireFrameMode (QString arg); + void setColor (QColor color); + void setScale (int scale); + + private: + QTreeView* view_; + QStandardItemModel* model_; + WindowsManagerPtr_t osg_; + QToolBox* toolBox_; + }; + } +} + +#endif // GEPETTO_GUI_BODYTREEWIDGET_HH diff --git a/include/gepetto/gui/color-map.hh b/include/gepetto/gui/color-map.hh new file mode 100644 index 0000000..358104a --- /dev/null +++ b/include/gepetto/gui/color-map.hh @@ -0,0 +1,72 @@ +#ifndef GEPETTO_GUI_COLORMAP_HH +#define GEPETTO_GUI_COLORMAP_HH + +#include <QColor> +#include <QDebug> + +namespace gepetto { + namespace gui { + class ColorMap { + public: + static QColor interpolate (std::size_t nbColors, std::size_t index) + { + if (index > nbColors) + qDebug() << "Nb colors:" << nbColors << "and index" << index; + return QColor::fromHslF((qreal)index / (qreal)nbColors, 1, 0.5); + } + + ColorMap (std::size_t nbColors) : + nbColors_ (nbColors), + currentIndex_ (0) + { + log2up_ = 0; + mask_ = 0; + std::size_t val = (nbColors > 0)?nbColors:1; + for (log2up_ = 0; val; ++log2up_, val >>= 1) mask_ = 2*mask_ + 1; + } + + QColor getColor (std::size_t index) const { + return ColorMap::interpolate(mask_, remap (index)); + } + + void getColor (std::size_t index, float color[4]) const { + QColor c = getColor(index); + color[0] = (float)c.redF(); + color[1] = (float)c.greenF(); + color[2] = (float)c.blueF(); + color[3] = (float)c.alphaF(); + } + + QColor nextColor () { + QColor color = getColor (currentIndex_); + currentIndex(currentIndex_ + 1); + return color; + } + + void currentIndex (std::size_t index) { + currentIndex_ = index % nbColors_; + } + + /// Reverse the order of the bits in index. + /// This increases the contrast between colors with close indexes. + std::size_t remap (const std::size_t& index) const { + std::size_t ret = 0; + std::size_t input = index; + for (std::size_t i = 0; i < log2up_; ++i) { + ret <<= 1; + if (input & 1) ++ret; + input >>= 1; + } + return ret; + } + + private: + std::size_t nbColors_; + std::size_t mask_; + std::size_t log2up_; + std::size_t currentIndex_; + }; + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_COLORMAP_HH diff --git a/include/gepetto/gui/config-dep.hh.in b/include/gepetto/gui/config-dep.hh.in new file mode 100644 index 0000000..38992d5 --- /dev/null +++ b/include/gepetto/gui/config-dep.hh.in @@ -0,0 +1,6 @@ +#ifndef GEPETTO_GUI_CONFIG_DEP_HH +# define PYTHON_CONFIG_DEP_HH + +#cmakedefine01 GEPETTO_GUI_HAS_PYTHONQT + +#endif // PYTHON_CONFIG_PYTHON_DEP_HH diff --git a/include/gepetto/gui/dialog/dialogloadenvironment.hh b/include/gepetto/gui/dialog/dialogloadenvironment.hh new file mode 100644 index 0000000..fa7d7ae --- /dev/null +++ b/include/gepetto/gui/dialog/dialogloadenvironment.hh @@ -0,0 +1,67 @@ +#ifndef GEPETTO_GUI_DIALOGLOADENVIRONMENT_HH +#define GEPETTO_GUI_DIALOGLOADENVIRONMENT_HH + +#include <QDialog> +#include <QComboBox> + +namespace Ui { + class DialogLoadEnvironment; +} + +namespace gepetto { + namespace gui { + class DialogLoadEnvironment : public QDialog + { + Q_OBJECT + + public: + explicit DialogLoadEnvironment(QWidget *parent = 0); + ~DialogLoadEnvironment(); + + struct EnvironmentDefinition { + QString name_, envName_, urdfFilename_, mesh_, package_, packagePath_, urdfSuf_, + srdfSuf_; + EnvironmentDefinition () {} + EnvironmentDefinition (QString name, QString envName, + QString package, QString packagePath, + QString urdfFilename, QString urdfSuffix, QString srdfSuffix, + QString meshDirectory) : + name_(name), envName_ (envName), urdfFilename_(urdfFilename), + mesh_(meshDirectory), package_ (package), packagePath_ (packagePath), + urdfSuf_(urdfSuffix), srdfSuf_(srdfSuffix) + {} + }; + + static void addEnvironmentDefinition (QString name, + QString envName, + QString package, + QString packagePath, + QString urdfFilename, + QString urdfSuffix, + QString srdfSuffix, + QString meshDirectory); + static QList <EnvironmentDefinition> getEnvironmentDefinitions (); + + EnvironmentDefinition getSelectedDescription () { + return selected_; + } + + private slots: + void accept(); + void meshSelect(); + void packagePathSelect(); + void envSelect(int index); + + private: + ::Ui::DialogLoadEnvironment *ui_; + QComboBox* defs_; + EnvironmentDefinition selected_; + + static QList <EnvironmentDefinition> definitions; + }; + } // namespace gui +} // namespace gepetto + +Q_DECLARE_METATYPE (gepetto::gui::DialogLoadEnvironment::EnvironmentDefinition) + +#endif // GEPETTO_GUI_DIALOGLOADENVIRONMENT_HH diff --git a/include/gepetto/gui/dialog/dialogloadrobot.hh b/include/gepetto/gui/dialog/dialogloadrobot.hh new file mode 100644 index 0000000..d7b821c --- /dev/null +++ b/include/gepetto/gui/dialog/dialogloadrobot.hh @@ -0,0 +1,72 @@ +#ifndef GEPETTO_GUI_DIALOGLOADROBOT_HH +#define GEPETTO_GUI_DIALOGLOADROBOT_HH + +#include <QDialog> +#include <QComboBox> + +namespace Ui { + class DialogLoadRobot; +} + +namespace gepetto { + namespace gui { + class DialogLoadRobot : public QDialog + { + Q_OBJECT + + public: + struct RobotDefinition { + QString name_, robotName_, urdfSuf_, srdfSuf_, mesh_, package_, packagePath_, modelName_, rootJointType_; + RobotDefinition () : rootJointType_ ("Freeflyer") {} + RobotDefinition (QString name, + QString robotName, + QString rootJointType, + QString modelName, + QString package, + QString packagePath, + QString urdfSuffix, + QString srdfSuffix, + QString meshDirectory) : + name_(name), robotName_ (robotName), urdfSuf_(urdfSuffix), srdfSuf_(srdfSuffix), mesh_(meshDirectory), + package_ (package), packagePath_(packagePath), modelName_ (modelName), + rootJointType_ (rootJointType){} + }; + + explicit DialogLoadRobot(QWidget *parent = 0); + ~DialogLoadRobot(); + + static void addRobotDefinition (QString name, + QString robotName, + QString rootJointType, + QString modelName, + QString package, + QString packagePath, + QString urdfSuffix, + QString srdfSuffix, + QString meshDirectory); + static QList <RobotDefinition> getRobotDefinitions (); + + RobotDefinition getSelectedRobotDescription () { + return selected_; + } + + private slots: + void accept(); + void meshSelect(); + void packagePathSelect(); + void robotSelect(int index); + + private: + ::Ui::DialogLoadRobot *ui_; + QComboBox* defs_; + RobotDefinition selected_; + + static QList <RobotDefinition> definitions; + static QStringList rootJointTypes; + }; + } // namespace gui +} // namespace gepetto + +Q_DECLARE_METATYPE (gepetto::gui::DialogLoadRobot::RobotDefinition) + +#endif // GEPETTO_GUI_DIALOGLOADROBOT_HH diff --git a/include/gepetto/gui/dialog/pluginmanagerdialog.hh b/include/gepetto/gui/dialog/pluginmanagerdialog.hh new file mode 100644 index 0000000..199b2fb --- /dev/null +++ b/include/gepetto/gui/dialog/pluginmanagerdialog.hh @@ -0,0 +1,125 @@ +#ifndef GEPETTO_GUI_PLUGINMANAGERDIALOG_HH +#define GEPETTO_GUI_PLUGINMANAGERDIALOG_HH + +#include <QDialog> +#include <QMap> +#include <QSignalMapper> +#include <QDir> +#include <QPluginLoader> +#include <QTableWidgetItem> + +#include <gepetto/gui/plugin-interface.hh> + +namespace Ui { + class PluginManagerDialog; +} + +namespace gepetto { + namespace gui { + class PluginManager { + public: + typedef QPair <QString, QPluginLoader*> Pair; + typedef QMap <QString, QPluginLoader*> Map; + + ~PluginManager () { + qDeleteAll (plugins_); + } + + const QMap <QString, QPluginLoader*>& plugins () const { + return plugins_; + } + + bool add (const QString& name, QWidget* parent = NULL, bool load = false); + + template <typename Interface> Interface* getFirstOf (); + + template <typename Interface> QList <Interface*> get (); + + static QIcon icon (const QPluginLoader* pl); + + static QString status (const QPluginLoader* pl); + + static void addPluginDir (const QString& path); + + bool initPlugin (const QString& name); + + bool unloadPlugin (const QString& name); + + private: + template <typename Interface> + static const Interface* const_instance_cast (const QPluginLoader* pl); + + QMap <QString, QPluginLoader*> plugins_; + static QList <QDir> pluginDirs_; + }; + + class PluginManagerDialog : public QDialog + { + Q_OBJECT + + public: + explicit PluginManagerDialog(PluginManager* pm, QWidget *parent = 0); + ~PluginManagerDialog(); + + public slots: + void onItemChanged (QTableWidgetItem* current, QTableWidgetItem* previous); + void contextMenu(const QPoint& pos); + + void load (const QString& name); + void unload (const QString& name); + + private: + static const std::size_t NAME; + static const std::size_t FILE; + static const std::size_t FULLPATH; + static const std::size_t VERSION; + + void updateList (); + + ::Ui::PluginManagerDialog *ui_; + + PluginManager* pm_; + QSignalMapper signalMapper_; + }; + + template <typename Interface> + Interface* PluginManager::getFirstOf () + { + foreach (QPluginLoader* p, plugins_) { + if (p->isLoaded()) { + PluginInterface* check = qobject_cast <PluginInterface*> (p->instance()); + if (check && check->isInit ()) { + Interface* pi = qobject_cast <Interface*> (p->instance()); + if (pi) return pi; + } + } + } + return NULL; + } + + template <typename Interface> + QList <Interface*> PluginManager::get () + { + QList <Interface*> list; + foreach (QPluginLoader* p, plugins_) { + if (p->isLoaded()) { + PluginInterface* check = qobject_cast <PluginInterface*> (p->instance()); + if (check && check->isInit ()) { + Interface* pi = qobject_cast <Interface*> (p->instance()); + if (pi) + list.append(pi); + } + } + } + return list; + } + + template <typename Interface> + const Interface* PluginManager::const_instance_cast (const QPluginLoader* pl) + { + return (const Interface*) qobject_cast <Interface*> (const_cast <QPluginLoader*>(pl)->instance()); + } + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_PLUGINMANAGERDIALOG_HH diff --git a/include/gepetto/gui/fwd.hh b/include/gepetto/gui/fwd.hh new file mode 100644 index 0000000..58c8da2 --- /dev/null +++ b/include/gepetto/gui/fwd.hh @@ -0,0 +1,25 @@ +#ifndef GEPETTO_GUI_FWD_HH +#define GEPETTO_GUI_FWD_HH + +#include <boost/shared_ptr.hpp> +#include <gepetto/gui/config-dep.hh> + +namespace gepetto { + namespace gui { + class MainWindow; + class OSGWidget; + class PickHandler; + class BodyTreeWidget; + + class ViewerCorbaServer; + + class WindowsManager; + typedef boost::shared_ptr <WindowsManager> WindowsManagerPtr_t; + +#if GEPETTO_GUI_HAS_PYTHONQT + class PythonWidget; +#endif + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_FWD_HH diff --git a/include/gepetto/gui/ledindicator.hh b/include/gepetto/gui/ledindicator.hh new file mode 100644 index 0000000..b9dfa1f --- /dev/null +++ b/include/gepetto/gui/ledindicator.hh @@ -0,0 +1,34 @@ +#ifndef GEPETTO_GUI_LEDINDICATOR_HH +#define GEPETTO_GUI_LEDINDICATOR_HH + +#include <QWidget> + +namespace gepetto { + namespace gui { + class LedIndicator : public QWidget + { + Q_OBJECT + + public: + LedIndicator (QWidget *parent = 0); + +signals: + void switched (bool on); + void mouseClickEvent (); + + public slots: + void switchLed(); + void switchLed(bool on); + + protected: + void paintEvent(QPaintEvent *); + void mouseReleaseEvent(QMouseEvent* event); + + private: + bool lit; + const int width, height; + }; + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_LEDINDICATOR_HH diff --git a/include/gepetto/gui/mainwindow.hh b/include/gepetto/gui/mainwindow.hh new file mode 100644 index 0000000..b604c70 --- /dev/null +++ b/include/gepetto/gui/mainwindow.hh @@ -0,0 +1,125 @@ +#ifndef GEPETTO_GUI_MAINWINDOW_HH +#define GEPETTO_GUI_MAINWINDOW_HH + +#include <QList> +#include <QStandardItemModel> +#include <QMainWindow> + +#include <gepetto/viewer/group-node.h> + +#include <gepetto/gui/fwd.hh> + +#include <gepetto/gui/ledindicator.hh> + +#include <gepetto/gui/omniorb/omniorbthread.hh> +#include <gepetto/gui/dialog/dialogloadrobot.hh> +#include <gepetto/gui/dialog/dialogloadenvironment.hh> +#include <gepetto/gui/dialog/pluginmanagerdialog.hh> + +#include <gepetto/gui/settings.hh> + +namespace Ui { + class MainWindow; +} + +namespace gepetto { + namespace gui { + class MainWindow : public QMainWindow + { + Q_OBJECT + + public: + Settings* settings_; + + explicit MainWindow(Settings* settings, QWidget *parent = 0); + ~MainWindow(); + + static MainWindow* instance (); + + void insertDockWidget (QDockWidget* dock, + Qt::DockWidgetArea area = Qt::AllDockWidgetAreas, + Qt::Orientation orientation = Qt::Horizontal); + + void removeDockWidget (QDockWidget* dock); + + BackgroundQueue &worker(); + + WindowsManagerPtr_t osg () const; + + OSGWidget* centralWidget() const; + + QList <OSGWidget*> osgWindows () const; + + BodyTreeWidget* bodyTree () const; + + PluginManager* pluginManager (); + + void emitSendToBackground (WorkItem* item); + +signals: + void sendToBackground (WorkItem* item); + void createView (QString name); + void refresh (); + void applyCurrentConfiguration(); + void configurationValidation(); + void selectJointFromBodyName(const QString bodyName); + + public slots: + void log (const QString& text); + void logError (const QString& text); + + void logJobStarted (int id, const QString& text); + void logJobDone (int id, const QString& text); + void logJobFailed (int id, const QString& text); + + OSGWidget* delayedCreateView (QString name = ""); + void requestRefresh (); + void requestApplyCurrentConfiguration (); + void requestConfigurationValidation (); + void configurationValidationStatusChanged (bool valid); + void configurationValidationStatusChanged (QStringList bodiesInCollision); + void requestSelectJointFromBodyName (const QString bodyName); + void onOpenPluginManager (); + + private slots: + OSGWidget* onCreateView(QString name); + OSGWidget* onCreateView(); + void openLoadRobotDialog (); + void openLoadEnvironmentDialog (); + + void handleWorkerDone (int id); + + void resetConnection (); + void about (); + + private: + void setupInterface (); + void createCentralWidget (); + + static MainWindow* instance_; + + ::Ui::MainWindow* ui_; + OSGWidget* centralWidget_; + QList <OSGWidget*> osgWindows_; +#if GEPETTO_GUI_HAS_PYTHONQT + PythonWidget* pythonWidget_; +#endif + + WindowsManagerPtr_t osgViewerManagers_; + CorbaServer* osgServer_; + BackgroundQueue backgroundQueue_; + QThread worker_; + + QCheckBox* collisionValidationActivated_; + LedIndicator* collisionIndicator_; + + QStandardItemModel *bodyTreeModel_; + + QMutex delayedCreateView_; + QStringList robotNames_; + QStringList lastBodiesInCollision_; + }; + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_MAINWINDOW_HH diff --git a/include/gepetto/gui/meta.hh b/include/gepetto/gui/meta.hh new file mode 100644 index 0000000..9cbbf8e --- /dev/null +++ b/include/gepetto/gui/meta.hh @@ -0,0 +1,33 @@ +#ifndef GEPETTO_GUI_META_HH +#define GEPETTO_GUI_META_HH + +#include <QString> + +namespace gepetto { + namespace gui { + template <typename T> struct Traits; + + template <> struct Traits <CORBA::String_var> { + typedef CORBA::String_var type; + static inline type from (const QString& s) { return (const char*)s.toLocal8Bit().data(); } + static inline type from (const std::string& s) { return s.c_str(); } + }; + + template <> struct Traits <QString> { + typedef CORBA::String_var CORBA_t; + static inline CORBA_t to_corba (const QString& s) { return (const char*)s.toLocal8Bit().data(); } + }; + + + template <typename In, typename Out, std::size_t Size> + inline void convertSequence (const In* in, Out (&out)[Size]) { + for (size_t i = 0; i < Size; ++i) out[i] = (Out)in[i]; + } + template <typename In, typename Out> + inline void convertSequence (const In* in, Out* out, const std::size_t& s) { + for (size_t i = 0; i < s; ++i) out[i] = (Out)in[i]; + } + } +} + +#endif // GEPETTO_GUI_META_HH diff --git a/include/gepetto/gui/omniorb/omniorbthread.hh b/include/gepetto/gui/omniorb/omniorbthread.hh new file mode 100644 index 0000000..6f2a108 --- /dev/null +++ b/include/gepetto/gui/omniorb/omniorbthread.hh @@ -0,0 +1,213 @@ +#ifndef GEPETTO_GUI_OMNIORBTHREAD_HH +#define GEPETTO_GUI_OMNIORBTHREAD_HH + +#include <assert.h> + +#include <QThread> +#include <QMutex> +#include <QTimerEvent> +#include <QElapsedTimer> + +#include "gepetto/gui/fwd.hh" +#include "gepetto/viewer/corba/fwd.hh" + +namespace gepetto { + namespace gui { + class WorkItem { + public: + WorkItem () : id_ (idGlobal++) {} + virtual ~WorkItem () {} + virtual void performWork () = 0; + int id () const { return id_; } + protected: + void id (int i) { id_ = i; } + private: + static int idGlobal; + int id_; + }; + + template <typename Caller, typename ReturnType> + class WorkItem_0 : public WorkItem { + public: + typedef ReturnType (Caller::* Method) (); + WorkItem_0 (Caller* c, Method m) : caller (c), method (m) {} + void performWork () { (caller->*method) (); } + private: + Caller* caller; + Method method; + }; + template <typename Caller, typename ReturnType, typename Arg0> + class WorkItem_1 : public WorkItem { + public: + typedef ReturnType (Caller::* Method) (Arg0); + WorkItem_1 (Caller* c, Method m, Arg0 a0) : caller (c), method (m), + arg0 (a0) {} + void performWork () { (caller->*method) (arg0); } + private: + Caller* caller; + Method method; + Arg0 arg0; + }; + template <typename Caller, typename ReturnType, typename Arg0, typename Arg1> + class WorkItem_2 : public WorkItem { + public: + typedef ReturnType (Caller::* Method) (Arg0,Arg1); + WorkItem_2 (Caller* c, Method m, Arg0 a0, Arg1 a1) : caller (c), method (m), + arg0 (a0), arg1 (a1) {} + void performWork () { (caller->*method) (arg0, arg1); } + private: + Caller* caller; + Method method; + Arg0 arg0; + Arg1 arg1; + }; + template <typename Caller, typename ReturnType, + typename Arg0, typename Arg1, typename Arg2> + class WorkItem_3 : public WorkItem { + public: + typedef ReturnType (Caller::* Method) (Arg0,Arg1,Arg2); + WorkItem_3 (Caller* c, Method m, Arg0 a0, Arg1 a1, Arg2 a2) : caller (c), method (m), + arg0 (a0), arg1 (a1), arg2 (a2) {} + void performWork () { (caller->*method) (arg0, arg1, arg2); } + private: + Caller* caller; + Method method; + Arg0 arg0; + Arg1 arg1; + Arg2 arg2; + }; + template <typename Caller, typename ReturnType, + typename Arg0, typename Arg1, typename Arg2, typename Arg3> + class WorkItem_4 : public WorkItem { + public: + typedef ReturnType (Caller::* Method) (Arg0,Arg1,Arg2,Arg3); + WorkItem_4 (Caller* c, Method m, Arg0 a0, Arg1 a1, Arg2 a2, Arg3 a3) : caller (c), method (m), + arg0 (a0), arg1 (a1), arg2 (a2), arg3 (a3) {} + void performWork () { (caller->*method) (arg0, arg1, arg2, arg3); } + private: + Caller* caller; + Method method; + Arg0 arg0; + Arg1 arg1; + Arg2 arg2; + Arg3 arg3; + }; + template <typename Caller, typename ReturnType, + typename Arg0, typename Arg1, typename Arg2, typename Arg3, typename Arg4> + class WorkItem_5 : public WorkItem { + public: + typedef ReturnType (Caller::* Method) (Arg0,Arg1,Arg2,Arg3,Arg4); + WorkItem_5 (Caller* c, Method m, Arg0 a0, Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4) : caller (c), method (m), + arg0 (a0), arg1 (a1), arg2 (a2), arg3 (a3), arg4 (a4) {} + void performWork () { (caller->*method) (arg0, arg1, arg2, arg3, arg4); } + private: + Caller* caller; + Method method; + Arg0 arg0; + Arg1 arg1; + Arg2 arg2; + Arg3 arg3; + Arg4 arg4; + }; + template <typename Caller, typename ReturnType, + typename Arg0, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> + class WorkItem_6 : public WorkItem { + public: + typedef ReturnType (Caller::* Method) (Arg0,Arg1,Arg2,Arg3,Arg4,Arg5); + WorkItem_6 (Caller* c, Method m, Arg0 a0, Arg1 a1, Arg2 a2, Arg3 a3, Arg4 a4, Arg5 a5) : caller (c), method (m), + arg0 (a0), arg1 (a1), arg2 (a2), arg3 (a3), arg4 (a4), arg5 (a5) {} + void performWork () { (caller->*method) (arg0, arg1, arg2, arg3, arg4, arg5); } + private: + Caller* caller; + Method method; + Arg0 arg0; + Arg1 arg1; + Arg2 arg2; + Arg3 arg3; + Arg4 arg4; + Arg5 arg5; + }; + + class ServerProcess : public QObject + { + Q_OBJECT + + public: + ServerProcess () ; + void waitForInitDone (); + +signals: + void done (); + + public slots: + virtual void init (); + virtual void processRequest (bool loop) = 0; + + protected: + QMutex initDone_; + }; + + class ViewerServerProcess : public ServerProcess + { + Q_OBJECT + + public: + ViewerServerProcess (graphics::corbaServer::Server* server); + + ~ViewerServerProcess (); + + + public slots: + void init (); + void processRequest (bool loop); + + private: + graphics::corbaServer::Server* server_; + }; + + class CorbaServer : public QObject + { + Q_OBJECT + + public: + CorbaServer(ServerProcess* process); + + ~CorbaServer (); + + void wait (); + + void waitForInitDone (); + + void start (); + +signals: + void process (bool); + + protected slots: + void timerEvent(QTimerEvent *event); + void processed (); + + private: + ServerProcess* control_; + QThread worker_; + int timerId_, interval_; + }; + + class BackgroundQueue : public QObject + { + Q_OBJECT + + public: + BackgroundQueue (QObject *parent = 0); + +signals: + void done (int workId); + void failed (int workId, const QString& text); + + public slots: + void perform(WorkItem* item); + }; + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_OMNIORBTHREAD_HH diff --git a/include/gepetto/gui/omniorb/url.hh b/include/gepetto/gui/omniorb/url.hh new file mode 100644 index 0000000..4e0507e --- /dev/null +++ b/include/gepetto/gui/omniorb/url.hh @@ -0,0 +1,24 @@ +#ifndef GEPETTO_GUI_OMNIORB_URL_HH +#define GEPETTO_GUI_OMNIORB_URL_HH + +#include <QString> + +namespace gepetto { + namespace gui { + namespace omniOrb { + static inline QString IIOPurl (const QString& host, const QString& port) + { + QString hp; + if (host.isEmpty ()) { + if (!port.isEmpty ()) hp = QString ("localhost:%1").arg (port); + } else { + if (port.isEmpty ()) hp = QString ("%1:2809").arg (host); + else hp = QString ("%1:%2").arg(host).arg(port); + } + return QString ("corbaloc:iiop:%1/NameService").arg (hp); + } + } // namespace omniOrb + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_OMNIORB_URL_HH diff --git a/include/gepetto/gui/osgwidget.hh b/include/gepetto/gui/osgwidget.hh new file mode 100644 index 0000000..1eec47c --- /dev/null +++ b/include/gepetto/gui/osgwidget.hh @@ -0,0 +1,123 @@ +#ifndef GEPETTO_GUI_OSGWIDGET_HH +#define GEPETTO_GUI_OSGWIDGET_HH + +#include <QString> +#include <QThread> +#include <QLabel> +#include <QTimer> + +#include <osg/ref_ptr> + +#include <osgQt/GraphicsWindowQt> +#include <gepetto/viewer/window-manager.h> + +#include <gepetto/gui/fwd.hh> +#include <gepetto/gui/windows-manager.hh> + +namespace gepetto { + namespace gui { + class RenderThread : public QThread { + public: + RenderThread () : + QThread (), viewerPtr (0), refreshRate (30) + {} + + virtual ~RenderThread(); + + osgViewer::ViewerRefPtr viewerPtr; + WindowsManagerPtr_t wsm_; + int refreshRate; + bool stop; + + // QThread interface + protected: + void run(); + }; + + class OSGWidget : public QWidget + { + Q_OBJECT + public: + typedef std::list <graphics::NodePtr_t> NodeList; + + enum Mode { + CAMERA_MANIPULATION, + NODE_SELECTION, + NODE_MOTION + }; + + OSGWidget( WindowsManagerPtr_t wm, + std::string name, + MainWindow* parent = 0, + Qt::WindowFlags f = 0, + osgViewer::ViewerBase::ThreadingModel threadingModel=osgViewer::Viewer::SingleThreaded ); + + virtual ~OSGWidget(); + + WindowsManager::WindowID windowID () const; + +signals: + void selected (QString name); + void requestMotion (graphics::NodePtr_t node, graphics::Node::Arrow direction, + float speed); + + public slots: + void loadURDF (const QString robotName, + const QString urdf_file_path, + const QString meshDataRootDir); + virtual void onHome(); + + void changeMode (Mode mode); + void selectionMode (); + void cameraManipulationMode (); + void addFloor(); + void attachToWindow (const std::string nodeName); + + protected: + + virtual void paintEvent( QPaintEvent* paintEvent ); + + private slots: + void transferSelected (QString name); + + private: + osgGA::EventQueue* getEventQueue() const; + + osg::ref_ptr<osgQt::GraphicsWindowQt> graphicsWindow_; + WindowsManagerPtr_t wsm_; + osg::ref_ptr<PickHandler> pickHandler_; + WindowsManager::WindowID wid_; + graphics::WindowManagerPtr_t wm_; + RenderThread render_; + osgViewer::ViewerRefPtr viewer_; + osg::ref_ptr <osgViewer::ScreenCaptureHandler> screenCapture_; + + QPoint selectionStart_; + QPoint selectionEnd_; + graphics::NodePtr_t selectedNode_; + + Mode mode_; + bool selectionFinished_; + + std::list <graphics::NodePtr_t> processPoint (); + std::list <graphics::NodePtr_t> processSelection(); + + struct InfoBox { + QSize size_; + QPixmap selection_, record_; + QLabel* label_; + + InfoBox (QWidget* parent); + void normalMode (); + void selectionMode (); + void recordMode (); + void setMode (Mode mode); + }; + InfoBox infoBox_; + + friend class PickHandler; + }; + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_OSGWIDGET_HH diff --git a/include/gepetto/gui/pick-handler.hh b/include/gepetto/gui/pick-handler.hh new file mode 100644 index 0000000..0bb88ce --- /dev/null +++ b/include/gepetto/gui/pick-handler.hh @@ -0,0 +1,52 @@ +#ifndef GEPETTO_GUI_PICK_HANDLER_HH +#define GEPETTO_GUI_PICK_HANDLER_HH + +#include <osgGA/GUIEventHandler> +#include <gepetto/viewer/node.h> + +#include <QObject> +#include <QModelIndex> + +#include <gepetto/gui/fwd.hh> + +namespace gepetto { + namespace gui { + class PickHandler : public QObject, public osgGA::GUIEventHandler + { + Q_OBJECT + + public: + PickHandler (WindowsManagerPtr_t wsm); + + virtual ~PickHandler(); + + virtual bool handle( const osgGA::GUIEventAdapter& ea, + osgGA::GUIActionAdapter& aa ); + + void select (graphics::NodePtr_t node); + + void getUsage (osg::ApplicationUsage &usage); + + private slots: + void bodyTreeCurrentChanged (const QModelIndex ¤t, + const QModelIndex &previous); + + signals: + void selected (QString name); + + private: + std::list <graphics::NodePtr_t> computeIntersection (osgGA::GUIActionAdapter& aa, + const float& x, const float& y); + + void setCameraToSelected (osgGA::GUIActionAdapter& aa, bool zoom); + + WindowsManagerPtr_t wsm_; + OSGWidget* parent_; + graphics::NodePtr_t last_; + bool pushed_; + float lastX_, lastY_; + }; + } +} + +#endif // GEPETTO_GUI_PICK_HANDLER_HH diff --git a/include/gepetto/gui/plugin-interface.hh b/include/gepetto/gui/plugin-interface.hh new file mode 100644 index 0000000..38c45a7 --- /dev/null +++ b/include/gepetto/gui/plugin-interface.hh @@ -0,0 +1,117 @@ +#ifndef GEPETTO_GUI_PLUGININTERFACE_HH +#define GEPETTO_GUI_PLUGININTERFACE_HH + +#include <QtGui> +#include <QWidget> + +#include <gepetto/gui/dialog/dialogloadrobot.hh> +#include <gepetto/gui/dialog/dialogloadenvironment.hh> + +#include <omniORB4/CORBA.h> + +namespace gepetto { + namespace gui { + const int DockKeyShortcutBase = Qt::CTRL + Qt::ALT; + + class PluginInterface { + public: + PluginInterface () + : errorMsg_ ("Not initalized") + , isInit_ (false) + {} + + virtual ~PluginInterface () {} + + virtual QString name () const = 0; + + void doInit () + { + try { + init (); + isInit_ = true; + } catch (const std::exception& e) { + errorMsg_ = QString (e.what ()); + } + } + + bool isInit () const + { + return isInit_; + } + + const QString& errorMsg () const + { + return errorMsg_; + } + + protected: + virtual void init () = 0; + + private: + QString errorMsg_; + bool isInit_; + }; + + class JointAction : public QAction { + Q_OBJECT + + public: + JointAction (const QString& actionName, const std::string& jointName, QObject* parent) + : QAction (actionName, parent) + , jointName_ (jointName) + { + connect (this, SIGNAL (triggered(bool)), SLOT(trigger())); + } + +signals: + void triggered (const std::string jointName); + + private slots: + void trigger () { + emit triggered(jointName_); + } + + private: + const std::string jointName_; + }; + + class JointModifierInterface { + public: + virtual ~JointModifierInterface () {} + + virtual JointAction* action (const std::string& jointName) const = 0; + }; + + class ModelInterface { + public: + virtual ~ModelInterface () {} + + virtual void loadRobotModel (DialogLoadRobot::RobotDefinition rd) = 0; + + virtual void loadEnvironmentModel (DialogLoadEnvironment::EnvironmentDefinition ed) = 0; + + virtual std::string getBodyFromJoint (const std::string& jointName) const = 0; + }; + + class CorbaInterface { + public: + virtual ~CorbaInterface () {} + + virtual void openConnection () = 0; + + virtual void closeConnection () = 0; + + /// return true if error was handled. + virtual bool corbaException (int jobId, const CORBA::Exception& excep) const = 0; + }; + } // namespace gui +} // namespace gepetto + +Q_DECLARE_INTERFACE (gepetto::gui::PluginInterface, "hpp-gui.plugins/0.0") +Q_DECLARE_INTERFACE (gepetto::gui::JointModifierInterface, "hpp-gui.plugin.joint-modifier/0.0") +Q_DECLARE_INTERFACE (gepetto::gui::ModelInterface, "hpp-gui.plugin.model/0.0") +Q_DECLARE_INTERFACE (gepetto::gui::CorbaInterface, "hpp-gui.plugin.corba/0.0") + + + +#endif // GEPETTO_GUI_PLUGININTERFACE_HH diff --git a/include/gepetto/gui/pythonwidget.hh b/include/gepetto/gui/pythonwidget.hh new file mode 100644 index 0000000..fe35546 --- /dev/null +++ b/include/gepetto/gui/pythonwidget.hh @@ -0,0 +1,40 @@ +#ifndef GEPETTO_GUI_PYTHONWIDGET_HH +#define GEPETTO_GUI_PYTHONWIDGET_HH + +#include <gepetto/gui/config-dep.hh> + +#if ! GEPETTO_GUI_HAS_PYTHONQT +# error "hpp-gui was not compile with PythonQt dependency." +#endif + +#include <QDockWidget> +#include <QLayout> +#include <QPushButton> +#include <PythonQt/PythonQt.h> +#include <PythonQt/PythonQt_QtAll.h> +#include <PythonQt/PythonQtScriptingConsole.h> + +namespace gepetto { + namespace gui { + class PythonWidget : public QDockWidget + { + Q_OBJECT + public: + explicit PythonWidget(QWidget *parent = 0); + void addToContext(QString const& name, QObject *obj); + virtual ~PythonWidget(); + + private: + PythonQtObjectPtr mainContext_; + PythonQtScriptingConsole* console_; + QPushButton* button_; + + signals: + + public slots: + void browseFile(); + }; + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_PYTHONWIDGET_HH diff --git a/include/gepetto/gui/safeapplication.hh b/include/gepetto/gui/safeapplication.hh new file mode 100644 index 0000000..7765042 --- /dev/null +++ b/include/gepetto/gui/safeapplication.hh @@ -0,0 +1,23 @@ +#ifndef GEPETTO_GUI_SAFEAPPLICATION_HH +#define GEPETTO_GUI_SAFEAPPLICATION_HH + +#include <QApplication> + +namespace gepetto { + namespace gui { + class SafeApplication : public QApplication + { + Q_OBJECT + + public: + explicit SafeApplication (int& argc, char ** argv); + + virtual bool notify(QObject* receiver, QEvent* e); + + signals: + void log (QString text); + }; + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_SAFEAPPLICATION_HH diff --git a/include/gepetto/gui/settings.hh b/include/gepetto/gui/settings.hh new file mode 100644 index 0000000..280748f --- /dev/null +++ b/include/gepetto/gui/settings.hh @@ -0,0 +1,75 @@ +#ifndef GEPETTO_GUI_SETTINGS_HH +#define GEPETTO_GUI_SETTINGS_HH + +#include <ostream> +#include <string> +#include <QString> +#include <QStringList> + +#include <gepetto/gui/dialog/pluginmanagerdialog.hh> + +namespace gepetto { + namespace gui { + class MainWindow; + + struct Settings { + std::string configurationFile; + std::string predifinedRobotConf; + std::string predifinedEnvConf; + + bool verbose; + bool noPlugin; + bool autoWriteSettings; + bool startGepettoCorbaServer; + + int refreshRate; + + std::string captureDirectory, captureFilename, captureExtension; + + /// Set up default values + Settings (); + + /// Update values accordingly with command arguments + int fromArgv (const int argc, char* const argv[]); + + /// Update settings from setting files + void fromFiles (); + + /// Write the settings to configuration files + void writeSettings (); + + /// Get a setting + QVariant getSetting (const QString & key, + const QVariant & defaultValue = QVariant()); + + PluginManager pluginManager_; + QStringList pluginsToInit_; + + void setMainWindow (MainWindow* main); + + void initPlugins (); + + std::ostream& print (std::ostream& os); + + private: + void readRobotFile (); + void readEnvFile (); + void readSettingFile (); + + void writeRobotFile (); + void writeEnvFile (); + void writeSettingFile (); + + void addRobotFromString (const std::string& rbtStr); + void addEnvFromString (const std::string& envStr); + void addPlugin (const QString& plg, bool init); + + inline void log (const QString& t); + inline void logError (const QString& t); + + MainWindow* mw; + }; + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_SETTINGS_HH diff --git a/include/gepetto/gui/tree-item.hh b/include/gepetto/gui/tree-item.hh new file mode 100644 index 0000000..a61b6c0 --- /dev/null +++ b/include/gepetto/gui/tree-item.hh @@ -0,0 +1,65 @@ +#ifndef GEPETTO_GUI_TREEITEM_HH +#define GEPETTO_GUI_TREEITEM_HH + +#include <QStandardItem> +#include <QItemDelegate> +#include <QDoubleSpinBox> +#include <QSlider> +#include <QMenu> +#include <QPushButton> +#include <QSignalMapper> + +#include <gepetto/gui/fwd.hh> +#include <gepetto/viewer/node.h> + +namespace gepetto { + namespace gui { + class BodyTreeItem; + + class BodyTreeItem : public QObject, public QStandardItem + { + Q_OBJECT + + public: + BodyTreeItem (QObject* parent, graphics::NodePtr_t node); + + virtual QStandardItem* clone () const; + + virtual int type() { + return QStandardItem::UserType+1; + } + + graphics::NodePtr_t node () const; + + void populateContextMenu (QMenu* menu); + + void setParentGroup (const std::string& parent); + + public: + void attachToWindow (unsigned int windowID); + + protected: + void init (); + + protected slots: + void setViewingMode (QString mode); + void setVisibilityMode (QString mode); + void removeFromGroup (); + void remove (); + void removeAll (); + void addLandmark (); + void deleteLandmark (); + + private: + graphics::NodePtr_t node_; + std::string parentGroup_; + + QSignalMapper vmMapper_; + QSignalMapper vizMapper_; + + friend class VisibilityItem; + }; + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_TREEITEM_HH diff --git a/include/gepetto/gui/ui/dialog_loadRobotFromFile.ui b/include/gepetto/gui/ui/dialog_loadRobotFromFile.ui new file mode 100644 index 0000000..3762c75 --- /dev/null +++ b/include/gepetto/gui/ui/dialog_loadRobotFromFile.ui @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Dialog</class> + <widget class="QDialog" name="Dialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>190</width> + <height>141</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <property name="fieldGrowthPolicy"> + <enum>QFormLayout::AllNonFixedFieldsGrow</enum> + </property> + <item row="0" column="0"> + <widget class="QLineEdit" name="lineEdit_robotName"> + <property name="placeholderText"> + <string>Robot name</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLineEdit" name="lineEdit_udrfFile"> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="placeholderText"> + <string>UDRF file</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLineEdit" name="lineEdit_meshDir"> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="placeholderText"> + <string>Mesh directory</string> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>lineEdit_robotName</tabstop> + <tabstop>lineEdit_udrfFile</tabstop> + <tabstop>lineEdit_meshDir</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>Dialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>174</x> + <y>131</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>140</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>Dialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>174</x> + <y>131</y> + </hint> + <hint type="destinationlabel"> + <x>189</x> + <y>140</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/include/gepetto/gui/ui/dialogloadenvironment.ui b/include/gepetto/gui/ui/dialogloadenvironment.ui new file mode 100644 index 0000000..40a7801 --- /dev/null +++ b/include/gepetto/gui/ui/dialogloadenvironment.ui @@ -0,0 +1,285 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>DialogLoadEnvironment</class> + <widget class="QDialog" name="DialogLoadEnvironment"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>440</width> + <height>418</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="8" column="1"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="envName"> + <property name="placeholderText"> + <string>Environment name</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QPushButton" name="pushButton_details"> + <property name="text"> + <string>Details</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Environment name</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="1" column="0" colspan="2"> + <widget class="QComboBox" name="comboBox_defs"/> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Select a predifined robot or enter your own descrption files.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="6" column="0"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>250</width> + <height>32</height> + </size> + </property> + </spacer> + </item> + <item row="7" column="0" colspan="2"> + <widget class="QGroupBox" name="groupBox_details"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Details</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="5" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>URDF Suffix</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QLineEdit" name="urdfSuffix"/> + </item> + <item row="3" column="1"> + <widget class="QLineEdit" name="packagePath"/> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="packageName"/> + </item> + <item row="4" column="1"> + <widget class="QLineEdit" name="urdfFilename"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Package</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>URDF filename</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QPushButton" name="pushButton_mesh"> + <property name="text"> + <string>Mesh directory</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QPushButton" name="pushButton_package"> + <property name="text"> + <string>Package path</string> + </property> + </widget> + </item> + <item row="7" column="1"> + <widget class="QLineEdit" name="meshDirectory"/> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>SRDF Suffix</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QLineEdit" name="srdfSuffix"/> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>comboBox_defs</tabstop> + <tabstop>envName</tabstop> + <tabstop>pushButton_details</tabstop> + <tabstop>packageName</tabstop> + <tabstop>pushButton_package</tabstop> + <tabstop>packagePath</tabstop> + <tabstop>urdfFilename</tabstop> + <tabstop>pushButton_mesh</tabstop> + <tabstop>meshDirectory</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>DialogLoadEnvironment</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>430</x> + <y>338</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>DialogLoadEnvironment</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>430</x> + <y>338</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>pushButton_details</sender> + <signal>toggled(bool)</signal> + <receiver>groupBox_details</receiver> + <slot>setVisible(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>430</x> + <y>126</y> + </hint> + <hint type="destinationlabel"> + <x>219</x> + <y>262</y> + </hint> + </hints> + </connection> + <connection> + <sender>pushButton_package</sender> + <signal>clicked()</signal> + <receiver>DialogLoadEnvironment</receiver> + <slot>packagePathSelect()</slot> + <hints> + <hint type="sourcelabel"> + <x>94</x> + <y>223</y> + </hint> + <hint type="destinationlabel"> + <x>219</x> + <y>163</y> + </hint> + </hints> + </connection> + <connection> + <sender>pushButton_mesh</sender> + <signal>clicked()</signal> + <receiver>DialogLoadEnvironment</receiver> + <slot>meshSelect()</slot> + <hints> + <hint type="sourcelabel"> + <x>94</x> + <y>293</y> + </hint> + <hint type="destinationlabel"> + <x>219</x> + <y>163</y> + </hint> + </hints> + </connection> + <connection> + <sender>comboBox_defs</sender> + <signal>currentIndexChanged(int)</signal> + <receiver>DialogLoadEnvironment</receiver> + <slot>envSelect(int)</slot> + <hints> + <hint type="sourcelabel"> + <x>219</x> + <y>40</y> + </hint> + <hint type="destinationlabel"> + <x>219</x> + <y>163</y> + </hint> + </hints> + </connection> + </connections> + <slots> + <slot>envSelect(int)</slot> + <slot>packagePathSelect()</slot> + <slot>meshSelect()</slot> + </slots> +</ui> diff --git a/include/gepetto/gui/ui/dialogloadrobot.ui b/include/gepetto/gui/ui/dialogloadrobot.ui new file mode 100644 index 0000000..ee8114e --- /dev/null +++ b/include/gepetto/gui/ui/dialogloadrobot.ui @@ -0,0 +1,301 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>DialogLoadRobot</class> + <widget class="QDialog" name="DialogLoadRobot"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>284</width> + <height>444</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="0" colspan="2"> + <widget class="QComboBox" name="comboBox_defs"/> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Select a predifined robot or enter your own descrption files.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="12" column="1"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QPushButton" name="pushButton_details"> + <property name="text"> + <string>Details</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="6" column="0" rowspan="2" colspan="2"> + <widget class="QGroupBox" name="groupBox_details"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Details</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="8" column="0"> + <widget class="QPushButton" name="pushButton_mesh"> + <property name="text"> + <string>Mesh directory</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="modelName"/> + </item> + <item row="4" column="1"> + <widget class="QLineEdit" name="packageName"/> + </item> + <item row="5" column="1"> + <widget class="QLineEdit" name="packagePath"/> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>SRDF suffix</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Package</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="rootJointType"/> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>URDF suffix</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Model name</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QLineEdit" name="urdfSuffix"/> + </item> + <item row="7" column="1"> + <widget class="QLineEdit" name="srdfSuffix"/> + </item> + <item row="8" column="1"> + <widget class="QLineEdit" name="meshDirectory"/> + </item> + <item row="5" column="0"> + <widget class="QPushButton" name="pushButton_package"> + <property name="text"> + <string>Package path</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Root joint type</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="3" column="0"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Robot name</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="robotName"> + <property name="placeholderText"> + <string>Robot name</string> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>comboBox_defs</tabstop> + <tabstop>robotName</tabstop> + <tabstop>pushButton_details</tabstop> + <tabstop>rootJointType</tabstop> + <tabstop>modelName</tabstop> + <tabstop>packageName</tabstop> + <tabstop>pushButton_package</tabstop> + <tabstop>packagePath</tabstop> + <tabstop>urdfSuffix</tabstop> + <tabstop>srdfSuffix</tabstop> + <tabstop>pushButton_mesh</tabstop> + <tabstop>meshDirectory</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>DialogLoadRobot</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>307</x> + <y>102</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>111</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>DialogLoadRobot</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>307</x> + <y>102</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>111</y> + </hint> + </hints> + </connection> + <connection> + <sender>pushButton_mesh</sender> + <signal>clicked()</signal> + <receiver>DialogLoadRobot</receiver> + <slot>meshSelect()</slot> + <hints> + <hint type="sourcelabel"> + <x>57</x> + <y>68</y> + </hint> + <hint type="destinationlabel"> + <x>158</x> + <y>55</y> + </hint> + </hints> + </connection> + <connection> + <sender>comboBox_defs</sender> + <signal>currentIndexChanged(int)</signal> + <receiver>DialogLoadRobot</receiver> + <slot>robotSelect(int)</slot> + <hints> + <hint type="sourcelabel"> + <x>210</x> + <y>19</y> + </hint> + <hint type="destinationlabel"> + <x>158</x> + <y>71</y> + </hint> + </hints> + </connection> + <connection> + <sender>pushButton_details</sender> + <signal>clicked(bool)</signal> + <receiver>groupBox_details</receiver> + <slot>setVisible(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>48</x> + <y>80</y> + </hint> + <hint type="destinationlabel"> + <x>135</x> + <y>189</y> + </hint> + </hints> + </connection> + <connection> + <sender>pushButton_package</sender> + <signal>clicked()</signal> + <receiver>DialogLoadRobot</receiver> + <slot>packagePathSelect()</slot> + <hints> + <hint type="sourcelabel"> + <x>68</x> + <y>247</y> + </hint> + <hint type="destinationlabel"> + <x>135</x> + <y>198</y> + </hint> + </hints> + </connection> + </connections> + <slots> + <slot>packagePathSelect()</slot> + <slot>meshSelect()</slot> + <slot>robotSelect(int)</slot> + </slots> +</ui> diff --git a/include/gepetto/gui/ui/mainwindow.ui b/include/gepetto/gui/ui/mainwindow.ui new file mode 100644 index 0000000..f7abb85 --- /dev/null +++ b/include/gepetto/gui/ui/mainwindow.ui @@ -0,0 +1,545 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>754</width> + <height>728</height> + </rect> + </property> + <property name="windowTitle"> + <string>HPP</string> + </property> + <property name="windowIcon"> + <iconset theme="hpp-gui"> + <normaloff/> + </iconset> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <widget class="QWidget" name="centralWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <property name="styleSheet"> + <string notr="true">image: url(:/img/gepetto.png);</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_5"/> + </widget> + <widget class="QMenuBar" name="menuBar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>754</width> + <height>23</height> + </rect> + </property> + <widget class="QMenu" name="menuFile"> + <property name="title"> + <string>&File</string> + </property> + <addaction name="actionCreate_view"/> + <addaction name="actionLoad_robot_from_file"/> + <addaction name="actionLoad_environment"/> + <addaction name="separator"/> + <addaction name="actionQuit"/> + </widget> + <widget class="QMenu" name="menuWindow"> + <property name="title"> + <string>&Window</string> + </property> + </widget> + <widget class="QMenu" name="menuTools"> + <property name="title"> + <string>&Tools</string> + </property> + <addaction name="actionRefresh"/> + <addaction name="actionPlugins"/> + <addaction name="actionReconnect"/> + </widget> + <widget class="QMenu" name="menuHelp"> + <property name="title"> + <string>&Help</string> + </property> + <addaction name="actionAbout"/> + </widget> + <addaction name="menuFile"/> + <addaction name="menuTools"/> + <addaction name="menuWindow"/> + <addaction name="menuHelp"/> + </widget> + <widget class="QToolBar" name="mainToolBar"> + <property name="windowTitle"> + <string>Main</string> + </property> + <property name="iconSize"> + <size> + <width>12</width> + <height>12</height> + </size> + </property> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + <addaction name="actionPlugins"/> + <addaction name="actionReconnect"/> + <addaction name="actionRefresh"/> + <addaction name="actionFetch_configuration"/> + </widget> + <widget class="QStatusBar" name="statusBar"/> + <widget class="QDockWidget" name="dockWidget_bodyTree"> + <property name="contextMenuPolicy"> + <enum>Qt::DefaultContextMenu</enum> + </property> + <property name="allowedAreas"> + <set>Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea</set> + </property> + <property name="windowTitle"> + <string>&Body tree</string> + </property> + <attribute name="dockWidgetArea"> + <number>1</number> + </attribute> + <widget class="gepetto::gui::BodyTreeWidget" name="bodyTreeContent"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QSplitter" name="splitter"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <widget class="QTreeView" name="bodyTree"> + <property name="contextMenuPolicy"> + <enum>Qt::CustomContextMenu</enum> + </property> + <property name="headerHidden"> + <bool>true</bool> + </property> + </widget> + <widget class="QScrollArea" name="scrollArea"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>254</width> + <height>129</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QToolBox" name="toolBox"> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="Info"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>236</width> + <height>80</height> + </rect> + </property> + <attribute name="label"> + <string>Transparency</string> + </attribute> + <layout class="QHBoxLayout" name="horizontalLayout"/> + </widget> + </widget> + </item> + </layout> + </widget> + </widget> + </widget> + </item> + </layout> + </widget> + </widget> + <widget class="QToolBar" name="osgToolBar"> + <property name="windowTitle"> + <string>OSG</string> + </property> + <property name="toolTip"> + <string>Selection</string> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + <addaction name="actionCamera_control_mode"/> + <addaction name="actionSelection"/> + <addaction name="actionHome"/> + <addaction name="actionAdd_floor"/> + </widget> + <widget class="QDockWidget" name="dockWidget_log"> + <property name="windowIcon"> + <iconset theme="dialog-information"> + <normaloff/> + </iconset> + </property> + <property name="windowTitle"> + <string>&Log</string> + </property> + <attribute name="dockWidgetArea"> + <number>1</number> + </attribute> + <widget class="QWidget" name="dockWidgetContents_4"> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QTextEdit" name="logText"> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="clearLogs"> + <property name="text"> + <string>Clear logs</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </widget> + <action name="actionCreate_view"> + <property name="icon"> + <iconset theme="window-new"> + <normaloff/> + </iconset> + </property> + <property name="text"> + <string>Create &view</string> + </property> + </action> + <action name="actionLoad_robot_from_file"> + <property name="icon"> + <iconset theme="list-add"> + <normaloff/> + </iconset> + </property> + <property name="text"> + <string>Load &robot from file</string> + </property> + <property name="shortcut"> + <string>Ctrl+R</string> + </property> + </action> + <action name="actionQuit"> + <property name="icon"> + <iconset theme="window-close"> + <normaloff/> + </iconset> + </property> + <property name="text"> + <string>&Quit</string> + </property> + <property name="shortcut"> + <string>Ctrl+Q</string> + </property> + </action> + <action name="actionLoad_environment"> + <property name="icon"> + <iconset theme="list-add"> + <normaloff/> + </iconset> + </property> + <property name="text"> + <string>Load &environment</string> + </property> + <property name="shortcut"> + <string>Ctrl+E</string> + </property> + </action> + <action name="actionSelection"> + <property name="icon"> + <iconset theme="edit-select"> + <normaloff/> + </iconset> + </property> + <property name="text"> + <string>Select</string> + </property> + <property name="toolTip"> + <string>Enter in select mode in the main OSG view</string> + </property> + </action> + <action name="actionHome"> + <property name="icon"> + <iconset theme="zoom-fit-best"> + <normaloff/> + </iconset> + </property> + <property name="text"> + <string>Home</string> + </property> + <property name="toolTip"> + <string>Zoom to fit</string> + </property> + </action> + <action name="actionPlugins"> + <property name="icon"> + <iconset theme="preferences-plugin"> + <normaloff/> + </iconset> + </property> + <property name="text"> + <string>&Plugins</string> + </property> + <property name="shortcut"> + <string>Ctrl+P</string> + </property> + </action> + <action name="actionCamera_control_mode"> + <property name="icon"> + <iconset theme="transform-move"> + <normaloff/> + </iconset> + </property> + <property name="text"> + <string>Camera</string> + </property> + <property name="toolTip"> + <string>Control the camera of the main OSG widget</string> + </property> + </action> + <action name="actionRefresh"> + <property name="icon"> + <iconset theme="view-refresh"> + <normaloff/> + </iconset> + </property> + <property name="text"> + <string>Refresh</string> + </property> + <property name="toolTip"> + <string>Refresh the interface (required if you are also using the python interface)</string> + </property> + <property name="shortcut"> + <string>F5</string> + </property> + </action> + <action name="actionAdd_floor"> + <property name="icon"> + <iconset resource="../../../../res/images.qrc"> + <normaloff>:/icons/floor.png</normaloff>:/icons/floor.png</iconset> + </property> + <property name="text"> + <string>Add floor</string> + </property> + <property name="toolTip"> + <string>Add a floor</string> + </property> + </action> + <action name="actionAbout"> + <property name="text"> + <string>&About...</string> + </property> + </action> + <action name="actionReconnect"> + <property name="icon"> + <iconset theme="network-connect"> + <normaloff/> + </iconset> + </property> + <property name="text"> + <string>Reset connection</string> + </property> + <property name="shortcut"> + <string>Shift+F5</string> + </property> + </action> + <action name="actionFetch_configuration"> + <property name="icon"> + <iconset theme="mail-receive"> + <normaloff/> + </iconset> + </property> + <property name="text"> + <string>Fetch configuration</string> + </property> + </action> + </widget> + <layoutdefault spacing="6" margin="11"/> + <customwidgets> + <customwidget> + <class>gepetto::gui::BodyTreeWidget</class> + <extends>QWidget</extends> + <header>gepetto/gui/bodytreewidget.hh</header> + <container>1</container> + <slots> + <slot>customContextMenu(QPoint)</slot> + </slots> + </customwidget> + </customwidgets> + <resources> + <include location="../../../../res/images.qrc"/> + </resources> + <connections> + <connection> + <sender>actionCreate_view</sender> + <signal>triggered()</signal> + <receiver>MainWindow</receiver> + <slot>onCreateView()</slot> + <hints> + <hint type="sourcelabel"> + <x>-1</x> + <y>-1</y> + </hint> + <hint type="destinationlabel"> + <x>441</x> + <y>358</y> + </hint> + </hints> + </connection> + <connection> + <sender>actionLoad_robot_from_file</sender> + <signal>triggered()</signal> + <receiver>MainWindow</receiver> + <slot>openLoadRobotDialog()</slot> + <hints> + <hint type="sourcelabel"> + <x>-1</x> + <y>-1</y> + </hint> + <hint type="destinationlabel"> + <x>441</x> + <y>358</y> + </hint> + </hints> + </connection> + <connection> + <sender>actionQuit</sender> + <signal>triggered()</signal> + <receiver>MainWindow</receiver> + <slot>close()</slot> + <hints> + <hint type="sourcelabel"> + <x>-1</x> + <y>-1</y> + </hint> + <hint type="destinationlabel"> + <x>441</x> + <y>358</y> + </hint> + </hints> + </connection> + <connection> + <sender>actionLoad_environment</sender> + <signal>triggered()</signal> + <receiver>MainWindow</receiver> + <slot>openLoadEnvironmentDialog()</slot> + <hints> + <hint type="sourcelabel"> + <x>-1</x> + <y>-1</y> + </hint> + <hint type="destinationlabel"> + <x>287</x> + <y>363</y> + </hint> + </hints> + </connection> + <connection> + <sender>actionPlugins</sender> + <signal>triggered()</signal> + <receiver>MainWindow</receiver> + <slot>onOpenPluginManager()</slot> + <hints> + <hint type="sourcelabel"> + <x>-1</x> + <y>-1</y> + </hint> + <hint type="destinationlabel"> + <x>376</x> + <y>363</y> + </hint> + </hints> + </connection> + <connection> + <sender>clearLogs</sender> + <signal>clicked(bool)</signal> + <receiver>logText</receiver> + <slot>clear()</slot> + <hints> + <hint type="sourcelabel"> + <x>230</x> + <y>693</y> + </hint> + <hint type="destinationlabel"> + <x>135</x> + <y>575</y> + </hint> + </hints> + </connection> + </connections> + <slots> + <slot>onCreateView()</slot> + <slot>openLoadRobotDialog()</slot> + <slot>showTreeContextMenu(QPoint)</slot> + <slot>updateJointTree(QModelIndex)</slot> + <slot>openLoadEnvironmentDialog()</slot> + <slot>reload()</slot> + <slot>onOpenPluginManager()</slot> + </slots> +</ui> diff --git a/include/gepetto/gui/ui/pluginmanagerdialog.ui b/include/gepetto/gui/ui/pluginmanagerdialog.ui new file mode 100644 index 0000000..028091d --- /dev/null +++ b/include/gepetto/gui/ui/pluginmanagerdialog.ui @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>PluginManagerDialog</class> + <widget class="QDialog" name="PluginManagerDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>300</height> + </rect> + </property> + <property name="windowTitle"> + <string>Plugin Manager</string> + </property> + <property name="windowIcon"> + <iconset theme="preferences-plugin"> + <normaloff/> + </iconset> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTableWidget" name="pluginList"> + <property name="contextMenuPolicy"> + <enum>Qt::CustomContextMenu</enum> + </property> + <column> + <property name="text"> + <string>Name</string> + </property> + </column> + <column> + <property name="text"> + <string>File</string> + </property> + </column> + <column> + <property name="text"> + <string>Version</string> + </property> + </column> + <column> + <property name="text"> + <string>FullPath</string> + </property> + </column> + </widget> + </item> + <item> + <widget class="QLabel" name="pluginMessage"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="pluginManagerButtonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>pluginManagerButtonBox</sender> + <signal>accepted()</signal> + <receiver>PluginManagerDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>pluginManagerButtonBox</sender> + <signal>rejected()</signal> + <receiver>PluginManagerDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/include/gepetto/gui/windows-manager.hh b/include/gepetto/gui/windows-manager.hh new file mode 100644 index 0000000..6529951 --- /dev/null +++ b/include/gepetto/gui/windows-manager.hh @@ -0,0 +1,85 @@ +#ifndef GEPETTO_GUI_WINDOWSMANAGER_HH +#define GEPETTO_GUI_WINDOWSMANAGER_HH + +#include <gepetto/gui/fwd.hh> +#include <gepetto/viewer/corba/windows-manager.hh> + +#include <gepetto/gui/meta.hh> +#include <QColor> +#include <QVector3D> + +namespace gepetto { + namespace gui { + template <> struct Traits <gepetto::corbaserver::Color_var> { + typedef gepetto::corbaserver::Color_var type; + static inline type from (const float* in) { + type out = new float[4]; + convertSequence <float, float> (in, out.inout(), 4); + return out; + } + static inline type from (const double* in) { + type out = new float[4]; + convertSequence <double, float> (in, out.inout(), 4); + return out; + } + static inline type from (const QColor& in) { + qreal v[4]; + in.getRgbF(&v[0],&v[1],&v[2],&v[3]); + return from (v); + } + }; + template <> struct Traits <gepetto::corbaserver::Position_var> { + typedef gepetto::corbaserver::Position_var type; + static inline type from (const float* in) { + type out = new float[4]; + convertSequence <float, float> (in, out.inout(), 4); + return out; + } + static inline type from (const double* in) { + type out = new float[4]; + convertSequence <double, float> (in, out.inout(), 4); + return out; + } + static inline type from (const QVector3D& in) { + qreal v[3]; v[0] = in.x(); v[1] = in.y(); v[2] = in.z(); + return from (v); + } + static inline type from (const int& in) { + qreal v[3]; v[0] = in / (qreal)50; v[1] = v[0]; v[2] = v[0]; + return from (v); + } + + }; + + template <> struct Traits <int> { + struct type { + float value; + const float& in() { return value; } + }; + + static inline type from(const int& in) { + type out; + out.value = (float)(in / 100.0); + return out; + } + }; + + class WindowsManager : public graphics::WindowsManager + { + public: + typedef graphics::WindowsManager Parent_t; + + static WindowsManagerPtr_t create (); + + WindowID createWindow(const char *windowNameCorba); + WindowID createWindow(const char *windowNameCorba, + osgViewer::Viewer* viewer, + osg::GraphicsContext *gc); + + protected: + WindowsManager (); + }; + } // namespace gui +} // namespace gepetto + +#endif // GEPETTO_GUI_WINDOWSMANAGER_HH diff --git a/res/floor.png b/res/floor.png new file mode 100644 index 0000000000000000000000000000000000000000..985d3fbb9aa7aaf66ccef0651a604a0669d3fe38 GIT binary patch literal 3597 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Ü`R@De(jvxJd3^U&U!K2+r(%9lNxv%g&t*4) z=D1LG<FN-l(_`+0TtKs!#i9h(0VXN4qCeZJUZCcpvU#erZd&KNZcHuRw~DMXUSvc8 zQv+yE<^=z}vjns!mm;E?2qlAE<8KmsooV9s-@Ux6!-EtOx*@6&@puFBbii2u;LFO2 z1~cwGHhiCA-|MWo*c^B5o08TM0UmE_h1KKn7UB|rvOEhLr^#b^BNly%w1HzZrj;V) zN`F&(2hfm%;8Qlh@-3g;j3n$;m86C*dFh4M$&432HBbQ6ovC40n2R5_BZZ#uE~$YS zhX{s<9Tq(kf!2ZVzrKy7WN0Bom(z=tcAO99LtvT2fq&xq%TF_US$uBnf(j>XKGgBJ zF@0KSq@J8%(YWJyy)E<AJM!ZTMG(>{$6DTtq>#*%in)0QEHE4_|3GMJD^_;=(4KTq zSjB+mrf1SSte&e&`(T!jDn%)d`p1wIT6tPO%ebN-!){J4ICB{db$PU9dx_#s2%s^K znm^jFUqhJ<pvdo6?A=!G!7o@FY|&?6Cyp?&!lOmh)AucI>`~hm>%{-@f9>;fL1^eX z6I)fQJpDj&UVGC>k9zhdA`kDeBT)<4Atee@-EZ2ZCvFV|KE7uJjHdQUzR-#>j-$9r zyNR6ZHlfA(62CWSULdI6=x)r<veoH&|5ao!zQxyFj9_ycb-PA=M`HVzA=M=d))3Oa z(oL+Fb(OlwcS^0jy_VYz=?ogg(Y_*IOf#c(STeScI0ItXglAQkIl2mNBG1lDkf!?0 zTS;kJDN*1vgRxsMHZ#mxK~phX3sLL!X-un}p5Hzw`01a`n-m1Ccl{{sidH1D@zMVq c54R2Ps=c5}w?hHn|Nc1u(iR1;hh4e*KXnzz761SM literal 0 HcmV?d00001 diff --git a/res/gepetto.png b/res/gepetto.png new file mode 100644 index 0000000000000000000000000000000000000000..bb0f97c08c6682cebeb8f23898dd0be54762ddcd GIT binary patch literal 151712 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�*?+ZZ1g_*;(rw-6<NFnzQWlD{&Y){m3jvHRaS9 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 literal 0 HcmV?d00001 diff --git a/res/images.qrc b/res/images.qrc new file mode 100644 index 0000000..9057897 --- /dev/null +++ b/res/images.qrc @@ -0,0 +1,18 @@ +<RCC> + <qresource prefix="/icons"> + <file>stop.png</file> + <file>pause.png</file> + <file>play.png</file> + <file>record.png</file> + <file>zoom_fit.png</file> + <file>refresh.png</file> + <file>floor.png</file> + </qresource> + <qresource prefix="/osg"> + <file>record.gif</file> + <file>selection.png</file> + </qresource> + <qresource prefix="/img"> + <file>gepetto.png</file> + </qresource> +</RCC> diff --git a/res/pause.png b/res/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..186f361f08b9d67858da54d9decd084f25072f2e GIT binary patch literal 1850 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 literal 0 HcmV?d00001 diff --git a/res/play.png b/res/play.png new file mode 100644 index 0000000000000000000000000000000000000000..3b64790b971704537cdf56306d98c15f0f7d1c16 GIT binary patch literal 1806 zcmV+p2l4ocP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU&ut`KgRCwB)S8GgDXBd8aIc)&}l|m^9 zw!pYbMgO=dE>pI+iFg@iCMHwnE?H)_EStDwW*{c}q5j)~GPC{g$1+TWj1*8|aq2Hw zCS!xl0aBnOD9~cC1$sT*`+hyAwzU_u;mzTk^L^j*y!ZD=V1>Wq$B(C^r>B1)kw}iB z7<@h-kkAkBnc)3DD3|Bv=6-B$Zho?ob0zWK*VotQB_}8Us^GW{6`MAJPOpdj{Ctqh zWFZSZUN4M|jlsCd1b+_<fXnS3ve|6=&!0bU!q>hRAs}mNYPz6QC_dWt<}RqH*aSY_ z2iC_{SXi)u!{G>7tWv2UH8lm&)}(<%3eex*54}A-;B>hzH8wVWf=j&5Lx4MT=FDV4 zL4mfm_8{;+9;T-s!mP!@Hjud^{g_+unxR%hR+g4MYj0~K%RFpoXjqT8?q{@&1b+JT z>512?s<L+P-VN6I$M9gx1k20IAVag0NTt$<BEF-wb4XUDRKb>)w-DiEy<YeJty{Og z$MgAE1UNLixvHv4`^vU$V49qOnVDHMDISg@23tHK5@d;mg#~arolw4^9G^pSUS8gZ zNaDL-62SyyXr`9J!opYILd_>9%<KSJ1aPJ?{U4M8&yWy=Vg=&>4CMxxnwnZ=FqCKA zzJ0q(3`~)Lq^_>6NUPQU^zM-(4A^3|222}#Fqv7-aqLQ#A=Mz7HH5tmw1QkNgVM56 z%8<=DIXSHZ0|Qn9mWrm=>2z&7ckX1oW@hICnoEPUp?gj)2Q(wJwEO^=AuJtbQc1|V z@I53ma~9mo!S?Nypx5i$2s1!n>(;GmOrw&G8!IsA=KUrVGz<{}LjuFYBXI1!qj2G3 z3n-LIe8xpyF9>^wIAqm|ip{`rTnS-{1Z0(!mB-4;%E06CfX!}??N`C<PNxG79XbdX zk%W>+2pJG7IBkoIYz@X45GG+00YySW!eO0G4|ZG-$@Jku+IT!Xv|hOiwQnC_?ocUX zyMvueB<zcjtJ6VZV!~m<CITvCUy_@f%Tgwq8H0r^K&5w8QWA7uyAJ#I?L~K70wq?% zc<ykyoUne~I<%O)gs_Q#oGKXk(u;@2(%i3!zY6kR9?){ANg~|5`8(7e*vH(V5&|>g zULuZe<`hb?k;$cEIi`E&s~GJ4B4e52<-N@J)B}jfpZ$Nqo;}sjj3g*cBUu6H8Db<L zX`u{A<WK7m&q&B5(fgCAiD&@@Y9h2@ifp{{A?qTwKz|>3`bHl7LWVIZ9s*G|iwE#L z5l{pO6k%j{c3p$dKl>E@><R)4Qvxl4Z932g<>ErevcFo<!BH(BR7RooF&EG;8#`ZT zR~MZ4@{0g?U|racFkB8-fE=yz;il1<*+&7B#uIXt53fWZLz4kLy}fX<{sg$)?q{Z? za3PEdY;w4El(30_$6~P<AB>J-bSmO!f#^g0OHE0EUIhR8tCQd%%@JG@6a$g=lG{wC z2QWK3Yb0zU;OOq|{&|!LV3}opjh6p{kd`=dLGN$9(D2PEaA9ikezjv}5T&{cYmM1F z1%yf1M8IV>n`f+6t7&LxkfoJ0N**(RVT>3I2I%Rz0Zok!sJWXxi>0|#=%SRacklL5 z!7~viVatS^kS#4O{kwYg>cceq(FUH(8RkC_0;jCB6n5-*4cw%89G{Cqozv}cLuaQE zrSr)2^z;~RTNdX59v>_f7Z>ZX8Wxu#0FPA>B9RbhKb~h-$qK-!MkHa`zS8;&Oir3R z+S}VN<F>~%s0IkoO<!N%0FroT?b@_NZB`c3&KCh7<`5D#kPtYP>z*6eVPs^)diLzu zIy~|r`9FLlqp_LCap{^yquH-krzK_~35jUp6=)hVIZ@DY3g-742!8M0Jqu3SHF(Sv z$`f%e3?@KGR7Ko(?%cVKBo5eY_JsVG3jAeOXv6XR&8B0@CT!0%GhA)I3jf`|Kab#h zaq9%iJf&Z>shC(fi3pPD%FNVg$HylMsqN;h%Ly61BaP%lRKaSA5B})u1EbLhqa&kT z=gyt`SOB+#e;Y*oFhN;^l389}zM-b3=G%;n3|(Pi5fl{_fku;wy<ZWs!R2(Z3O6!5 zj3e7H*zNX-j*gB~gM))Z`1+9$bnfT+G((}jnTC?CR;xAD)zvlG+1YQXR7yS1`$7(( zfWr}d9J8qx)69s~mGXQJg{I%7=lwJbe$NR+l2B4mQc)6uChB1KEz|di5M+x2u=_<n wP9s@_?5+~JX!u^A5L^x+n7u1G^nU>c0EW+}1GA~clmGw#07*qoM6N<$g21I+?f?J) literal 0 HcmV?d00001 diff --git a/res/record.gif b/res/record.gif new file mode 100644 index 0000000000000000000000000000000000000000..29606ec334a16b0ce9407766ff540af7c18be82a GIT binary patch literal 1232 zcmds$`A?H~9LFCR68J!&w0-)NLpd9+auv!|wzRbc$|W!em;s~p1gdhm2?~mWZ9NE7 z*v5hm1et6yDPhCOoCPW&!5Lt4Dj7?0Ey^K^MatltF#I?6&MU9qUq8I##Icc45;x2Z zGhrASC^P(U9NjKLy)vYhq3;i%_8fFQccwYl&?+50pKVfoY&^qXQzYqY;@;I~ylco* z7bmI9Q)eo6Yme~OFK4aSXQQJ*#<FnJso1qM@ko)5lo_U?kkLH$#^-{~3L!e3V94@X z%k$Ca_?Qlct`%~SEE1K(Y!q|RasFniBT92Zd%ck)07-*TLAWY0%oIys72zns(G>59 zlAKVAvnj<H?b)UMkb$z8O?<xwVW28G5^-T88rGx06aj17M8aw~tVY1wa6o*ArD!q| zQcWVpTLJOnBf3%KxWa)qVemQ(Ua{d-C@ivJferH^@G=Bm1jAeq=mSB&Z4T*m40Sn% zYKWldI8=Q!F%wDG$1rB2h*>W2oXb!JGX4nwoge5}@V7tw?oXNyCg1k9dmKuC$|0U` zh;dICXTmKv_|=0n%(NTxqm24duDIH%-0Zs?LCt_J0<PlFx(yv#aA=`JJr3t-&_sbI zDkvPFiVPRYP-_P#Nl<AI6(lGpK`9A}ZJ^Kwq&6S{_!J;-+a!|I!C@bjdI-l4((wa0 zz8}X6cDfvPagn*Y7Pz_|VKR?-dl$1<Wr2ZZ!NKKh_9-5(N+75f3TwpTbIHk93JaTL zvewGVZ>p<1>gqb>^1;5oU;6up@7>c34vyTvuN@lN+S<bYk8}Um!VJUiV669X?>~WA zZDA$WF7dr>L+7lhemP^k?IUusXF@-onCY9?oN%KuGx0eu>zdSum#WcN*dGe}@h(33 zr?0D-6>9=BuT$C)!j~b;MfZSo3dVa%7VNMkxJM^6>fztM-D|f;M9#0dnbsN6fUxv^ zmRHkR#NCCEwzH3^+08N%TPvmrdg#*&O}e3H{Y6Sz#nk?ku6k?9N~EUUXS%bn#$s~Q z>%x~DMUHQdsJ&*EP#Bjlvu`9g^Ka5Fls51mSU-%Q1cguCF*dWS1ipH$Ze*U`ZS0#% zG9-KvQWfZ{t#yB3^VfIErE62%i}cVlwcfU(>lURmaVI`0skeOO{>(aUzK7B1`E%pa z!+|1x$LOPu3F};gMDoGlXUm0})fTTPNkDSWSld^nalFP|^u=!V=*~;U=GlTCTMsS8 z!YRHEx9S_Pbg4<DJP`~u^~q^Tv=jMfi?p+HuY69JjnC=M6%j#5)jLk+>m&-VHlCq@ z)x{c?yT}v{mX62%FjIIozoAVA+>)6qJ(M(6yk}$Tu(iKLoH6d-eJNec?2xUt#U1YI Op8Hz%(|jrq<NgN+8l-Rl literal 0 HcmV?d00001 diff --git a/res/record.png b/res/record.png new file mode 100644 index 0000000000000000000000000000000000000000..bd37ba8bfbaae07876727e83899d48f22257b089 GIT binary patch literal 2038 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 U{*FfG%K!iX07*qoM6N<$g8LrassI20 literal 0 HcmV?d00001 diff --git a/res/refresh.png b/res/refresh.png new file mode 100644 index 0000000000000000000000000000000000000000..c6c72b289d4c7ab351f65c3fe83715033f0947d1 GIT binary patch literal 2061 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 literal 0 HcmV?d00001 diff --git a/res/selection.png b/res/selection.png new file mode 100644 index 0000000000000000000000000000000000000000..1bbfc065a793a398f70bdf9f4c0e8a84893d13eb GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1SJ1Ryj={WI14-?iy0WWg+Z8+Vb&Z8pkSb< zi(^Q|oTMNA$p;Lw4z6I`vN?fS=zz#UEej3Z1FGJ89yM-mh)P%xEI4r)&nXLutqluU zuP`k>IVFfYBW~8E3rty!f!uDo5=>%1!x;YmXJ(l2Yq8$^IZ>xTd{0+Dmvv4FO#lLA BFsuLo literal 0 HcmV?d00001 diff --git a/res/stop.png b/res/stop.png new file mode 100644 index 0000000000000000000000000000000000000000..e296377034f31c0106de1f986ed645e02347a350 GIT binary patch literal 1797 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 literal 0 HcmV?d00001 diff --git a/res/zoom_fit.png b/res/zoom_fit.png new file mode 100644 index 0000000000000000000000000000000000000000..4b6873b4a812137014cdbd2cb86c04b0c8064e71 GIT binary patch literal 1292 zcmV+n1@roeP)<h;3K|Lk000e1NJLTq001BW001Be0ssI2{21+{0000ibVXQnLvm$d zbZKvHAXI5>WdK)YWFRszAWC&?ATls9Fd#89IxsXkG&CSBFg7qSdj$x}00007bV*G` z2igY}5d{NN41(+c000SaNLh0L01m?d01m?e$8V@)00004XF*Lt006O%3;baP000DI zNkl<Zc-pmATZola6yAIP|2fVDB6FsPKoBI&LZ}9kk%<W(v`8AGo53i86EO?~rTLIb zHJOokfxsrDP{;}g%9^4<l0nN0iW6awDGow!<uvv(mvh<w?%Qi$=Rbp&hgoNx|NLj| zwZCtzeOY^RrPQ1ahuJJh=};%0DbR;^tiHLc;EY4?hOfehA*@W@f&j?iNX?(6^XC?e z#k#t>`uh6g7yk6Pi4ck4Lh!_K7<8#vmMN(<^Gr{*E}fW|n4FxPnwq-!*BC5ALqnDz zhYp}L5ru>o5>4Qv_Zcullc|d26{)IHvkad7ebusuG7_JMB{1j>4Gk1HFQx*T3SkF_ z6S^Z{HV-biLW*gUm8-m5MJft7Qpy<!eC%D%Kl#PLPjv+yH))Q51K1I0<xp<2Wb4+f z`tIZ~T30-}D9oSvG3amu`sP>HC!C{CUX$pVQ_i<^Z}|M%V}b^A=+`TG0+T(41+n)X z{Bp;(H+A^JDL3=1r#j)m;#=R}zGeSshtU@ZJhuYFU?qCoP0x2e*z@WBeSi}Nl+c9} zo1bfi=i57X8zwz-iI{-^yjU|dt2Vms*WUR4n|>RtjhYcCi;V+cAAzU000B607M38< z4SLOZ#jLG)VeR?TKXW_V+-?Ym1vz)><g+inOb($Vt!z<Cz|DI1qP-bwZEL@F^)mcJ z)OPgQ$dyaWAAdsleeT3SO(QT_+vRAKF-ODiU;Mz0e@Dp@TE|AOFJAIs2q|uL;~5Az z&6Qb5Rym9M@Oe$mnXGz*YNg!Nd~XQI`!l;;OkIfxn5$)O!E&>wBBnGgP@MX`Se)bS zX7{;D!fMe(gy@2g>Ow3kR0<Xa6USu}iTQ-->b5^s00&ZwrDkFcuga8ihvo@P1y->q zW47kl>d&OC8frYt<&w9PzlsraXo9)=9&(6qN!5Qh#!%3dGo*#$==FaT!30m&7a|q& z6q+ET(<5|nXBHh>>e|TFyY8MF@#)rknwl?P`onf2u+WNLSvc?PMx(Py#iCgmyKwHz z`~?e9-l>mMyk~6Tq9td3IgwF(aYqA{-^n;5DpDVQUg0`8aP*PKT9w0<8ke5*7qYCa z{b>JJHX5hEk<o!;38+C;^#N;RJb2*al}~qsz$t5~?09<PGta%$_t9Q&sp>$d-3LNd z!ntaWJ$ygx-PXCWo8a{P>#ViiiZtWkTDy8)fA_7;h64z|iPv!;04tiODsod#*QTw# zZmgA!jyN=#3KrkG^}Ss^8#~b#2)W&330Ai~OarA}S=-UO?-S|fYMRREnNy{9^&P^Q zoYCrx&t!Y(<1zz|#>U1Y$4-|j+RfZ5R8&D}H>>DYVXt2pR|F0{(Enpcd&~Ivc&SvH zfxw#pU#j5lp$bWM8~38j--{r)a+OH(1m1)^emM0TylJ)RrFBO)J3~+|m-7U}BY(3R z(JN91c)NE~-0W&W`0U-T2iM<c2^if{XM>}qrR9J7F?aih(~$xI0000<MNUMnLSTa6 CM`wos literal 0 HcmV?d00001 diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt new file mode 100644 index 0000000..cfe0872 --- /dev/null +++ b/src/gui/CMakeLists.txt @@ -0,0 +1,118 @@ +# +# Copyright (c) 2015 CNRS +# Authors: Joseph Mirabel +# +# +# This file is part of gepetto-gui +# gepetto-gui is free software: you can redistribute it +# and/or modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation, either version +# 3 of the License, or (at your option) any later version. +# +# gepetto-gui is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Lesser Public License for more details. You should have +# received a copy of the GNU Lesser General Public License along with +# gepetto-gui If not, see +# <http://www.gnu.org/licenses/>. + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET(CMAKE_MODULE_PATH + ${CMAKE_SOURCE_DIR}/cmake-modules/ + ${CMAKE_MODULE_PATH}) + +FIND_PACKAGE(Qt4 REQUIRED QtCore QtGui QtOpenGl QtNetwork) +FINDPYTHON(2.7 EXACT) +FIND_PACKAGE(PythonQt COMPONENTS QtAll) + +ADD_REQUIRED_DEPENDENCY("openscenegraph >= 3.2") +ADD_REQUIRED_DEPENDENCY("openscenegraph-osgQt") +ADD_REQUIRED_DEPENDENCY("openthreads >= 2.6") +ADD_REQUIRED_DEPENDENCY("gepetto-viewer-corba") + +SET(BOOST_COMPONENTS program_options system thread regex) +SEARCH_FOR_BOOST () + +FIND_PACKAGE("X11") + +# Activate hpp-util logging if requested +SET (HPP_DEBUG FALSE CACHE BOOL "trigger hpp-util debug output") +IF (HPP_DEBUG) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHPP_DEBUG") +ENDIF() + +# Configure the project + +SET (${PROJECT_NAME}_SOURCES + ${CMAKE_BINARY_DIR}/src/gui/main.cc + settings.cc + windows-manager.cc + safeapplication.cc + mainwindow.cc + osgwidget.cc + pick-handler.cc + tree-item.cc + omniorbthread.cc + bodytreewidget.cc + ledindicator.cc + dialog/dialogloadrobot.cc + dialog/dialogloadenvironment.cc + dialog/pluginmanagerdialog.cc + ) + +SET(GEPETTO_GUI_HAS_PYTHONQT ${PYTHONQT_FOUND} CACHE BOOL "Use PythonQt dependency") + +IF(GEPETTO_GUI_HAS_PYTHONQT) + INCLUDE_DIRECTORIES("${PYTHON_INCLUDE_DIR}" "${PYTHONQT_INCLUDE_DIR}") + + SET (${PROJECT_NAME}_HEADERS_MOC + ${${PROJECT_NAME}_HEADERS_MOC} + ${CMAKE_SOURCE_DIR}/include/gepetto/gui/pythonwidget.hh) + SET (${PROJECT_NAME}_SOURCES + ${${PROJECT_NAME}_SOURCES} + pythonwidget.cc) +ELSE (GEPETTO_GUI_HAS_PYTHONQT) + MESSAGE(STATUS "Skipping PythonQt settings") +ENDIF(GEPETTO_GUI_HAS_PYTHONQT) + +SET (${PROJECT_NAME}_HEADERS + ${${PROJECT_NAME}_HEADERS_MOC} + ${${PROJECT_NAME}_HEADERS_NO_MOC} + ) + +# Compile meta-objects and executable + +QT4_WRAP_CPP(${PROJECT_NAME}_HEADERS_MOCED ${${PROJECT_NAME}_HEADERS_MOC}) +QT4_WRAP_UI(${PROJECT_NAME}_FORMS_HEADERS ${${PROJECT_NAME}_FORMS}) +QT4_ADD_RESOURCES(${PROJECT_NAME}_RESOURCES_RCC ${${PROJECT_NAME}_RESOURCES}) + +INCLUDE(${QT_USE_FILE}) +ADD_DEFINITIONS(${QT_DEFINITIONS}) + +ADD_EXECUTABLE(gepetto-gui ${${PROJECT_NAME}_SOURCES} + ${${PROJECT_NAME}_HEADERS_MOCED} + ${${PROJECT_NAME}_HEADERS_NO_MOC} + ${${PROJECT_NAME}_FORMS_HEADERS} + ${${PROJECT_NAME}_RESOURCES_RCC} + ) + +INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/src/gui) + +TARGET_LINK_LIBRARIES(gepetto-gui ${QT_LIBRARIES}) +PKG_CONFIG_USE_DEPENDENCY(gepetto-gui openscenegraph) +PKG_CONFIG_USE_DEPENDENCY(gepetto-gui openthreads) +PKG_CONFIG_USE_DEPENDENCY(gepetto-gui gepetto-viewer-corba) +PKG_CONFIG_USE_DEPENDENCY(gepetto-gui openscenegraph-osgQt) +IF (GEPETTO_GUI_HAS_PYTHONQT) + TARGET_LINK_LIBRARIES(gepetto-gui ${PYTHONQT_LIBRARIES}) +ENDIF (GEPETTO_GUI_HAS_PYTHONQT) +TARGET_LINK_LIBRARIES(gepetto-gui ${X11_LIBRARIES} ${Boost_LIBRARIES}) + +INSTALL(TARGETS gepetto-gui DESTINATION lib) + +INSTALL(FILES ${CMAKE_BINARY_DIR}/src/gui/gepetto-gui + DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE + ) diff --git a/src/gui/bodytreewidget.cc b/src/gui/bodytreewidget.cc new file mode 100644 index 0000000..591ade1 --- /dev/null +++ b/src/gui/bodytreewidget.cc @@ -0,0 +1,168 @@ +#include <gepetto/gui/bodytreewidget.hh> + +#include <gepetto/gui/tree-item.hh> +#include <gepetto/gui/mainwindow.hh> +#include <gepetto/gui/windows-manager.hh> +#include <gepetto/gui/osgwidget.hh> +#include <gepetto/gui/meta.hh> + +#include <QSignalMapper> +#include <QColorDialog> + +static void addSelector (QToolBox* tb, QString title, QStringList display, QStringList command, + QObject* receiver, const char* slot) { + QWidget* newW = new QWidget(); + newW->setObjectName(title); + QSignalMapper* mapper = new QSignalMapper (tb); + QHBoxLayout* layout = new QHBoxLayout(newW); + layout->setSpacing(6); + layout->setContentsMargins(11, 11, 11, 11); + layout->setObjectName(title + "_layout"); + for (int i = 0; i < display.size(); ++i) { + QPushButton* button = new QPushButton(display[i], newW); + button->setObjectName(title + "_button_" + display[i]); + layout->addWidget (button); + mapper->setMapping(button, command[i]); + QObject::connect (button, SIGNAL(clicked(bool)), mapper, SLOT(map())); + } + receiver->connect (mapper, SIGNAL(mapped(QString)), slot); + tb->addItem(newW, title); +} + +static void addColorSelector (QToolBox* tb, QString title, QObject* receiver, const char* slot) { + QWidget* newW = new QWidget(); + newW->setObjectName(title); + QHBoxLayout* layout = new QHBoxLayout(); + newW->setLayout(layout); + layout->setSpacing(6); + layout->setContentsMargins(11, 11, 11, 11); + layout->setObjectName(title + "_layout"); + QPushButton* button = new QPushButton("Select color", newW); + button->setObjectName(title + "_buttonSelect"); + layout->addWidget (button); + + QColorDialog* colorDialog = new QColorDialog(newW); + colorDialog->setObjectName(title + "_colorDialog"); + colorDialog->setOption(QColorDialog::ShowAlphaChannel, true); + + colorDialog->connect(button, SIGNAL(clicked()), SLOT(open())); + receiver->connect (colorDialog, SIGNAL(colorSelected(QColor)), slot); + tb->addItem(newW, title); +} + +static void addSlider (QToolBox* tb, QString title, QObject* receiver, const char* slot) { + QSlider* slider = new QSlider (Qt::Horizontal); + slider->setMinimum(0); + slider->setMaximum(100); + slider->setObjectName(title); + + receiver->connect (slider, SIGNAL(valueChanged(int)), slot); + tb->addItem(slider, title); +} + +namespace gepetto { + namespace gui { + void BodyTreeWidget::init(QTreeView* view, QToolBox *toolBox) + { + MainWindow* main = MainWindow::instance(); + osg_ = main->osg(); + view_ = view; + toolBox_ = toolBox; + model_ = new QStandardItemModel (this); + view_->setModel(model_); + view_->setSelectionMode(QAbstractItemView::SingleSelection); + + connect (main, SIGNAL (refresh()), SLOT (reloadBodyTree())); + connect (view_, SIGNAL (customContextMenuRequested(QPoint)), SLOT(customContextMenu(QPoint))); + + toolBox_->removeItem(0); + addSlider(toolBox_, "Transparency", this, SLOT(setTransparency(int))); + addSelector (toolBox_, "Visibility", + QStringList () << "On" << "Always on top" << "Off", + QStringList () << "ON" << "ALWAYS_ON_TOP" << "OFF", + this, SLOT(setVisibilityMode(QString))); + addSelector (toolBox_, "Wireframe mode", + QStringList () << "Fill" << "Both" << "Wireframe", + QStringList () << "FILL" << "FILL_AND_WIREFRAME" << "WIREFRAME", + this, SLOT(setWireFrameMode(QString))); + addColorSelector(toolBox_, "Color", this, SLOT(setColor(QColor))); + addSlider(toolBox_, "Scale", this, SLOT(setScale(int))); + } + + QTreeView* BodyTreeWidget::view () + { + return view_; + } + + void BodyTreeWidget::selectBodyByName(const QString bodyName) + { + QList<QStandardItem*> matches; + if (!bodyName.isEmpty() && !bodyName.isNull()) { + matches = model_->findItems(bodyName, Qt::MatchFixedString + | Qt::MatchCaseSensitive + | Qt::MatchRecursive); + } + if (matches.empty()) { + qDebug () << "Body" << bodyName << "not found."; + view_->clearSelection(); + } else { + view_->setCurrentIndex(matches.first()->index()); + } + } + + void BodyTreeWidget::selectBodyByName (const std::string& bodyName) + { + qDebug () << "Use QString instead of std::string"; + return selectBodyByName (QString::fromStdString (bodyName)); + } + + void BodyTreeWidget::reloadBodyTree() + { + model_->clear(); + std::vector <std::string> sceneNames = osg_->getSceneList (); + for (unsigned int i = 0; i < sceneNames.size(); ++i) { + graphics::GroupNodePtr_t group = osg_->getScene(sceneNames[i]); + if (!group) continue; + addBodyToTree(group); + } + } + + void BodyTreeWidget::addBodyToTree(graphics::GroupNodePtr_t group) + { + model_->appendRow(new BodyTreeItem (this, group)); + } + + void BodyTreeWidget::customContextMenu(const QPoint &pos) + { + QModelIndex index = view_->indexAt(pos); + if(index.isValid()) { + BodyTreeItem *item = dynamic_cast <BodyTreeItem*> + (model_->itemFromIndex(index)); + if (!item) return; + MainWindow* main = MainWindow::instance (); + QMenu contextMenu (tr("Node")); + item->populateContextMenu (&contextMenu); + QMenu* windows = contextMenu.addMenu(tr("Attach to window")); + foreach (OSGWidget* w, main->osgWindows ()) { + JointAction* ja = new JointAction (w->objectName(), item->node()->getID(), windows); + windows->addAction (ja); + w->connect(ja, SIGNAL(triggered(std::string)), SLOT(attachToWindow(std::string))); + } + contextMenu.exec(view_->mapToGlobal(pos)); + } + } + + void BodyTreeWidget::changeAlphaValue(const float& alpha) + { + QSlider *tr = qobject_cast<QSlider *>(toolBox_->widget(0)); + + tr->setValue((int)alpha * 100); + } + + GEPETTO_GUI_BODYTREE_IMPL_FEATURE (setTransparency, int, int, setAlpha) + GEPETTO_GUI_BODYTREE_IMPL_FEATURE (setVisibilityMode, QString, CORBA::String_var, setVisibility) + GEPETTO_GUI_BODYTREE_IMPL_FEATURE (setWireFrameMode, QString, CORBA::String_var, setWireFrameMode) + GEPETTO_GUI_BODYTREE_IMPL_FEATURE (setColor, QColor, gepetto::corbaserver::Color_var, setColor) + GEPETTO_GUI_BODYTREE_IMPL_FEATURE (setScale, int, gepetto::corbaserver::Position_var, setScale) + } +} diff --git a/src/gui/dialog/dialogloadenvironment.cc b/src/gui/dialog/dialogloadenvironment.cc new file mode 100644 index 0000000..d5ec383 --- /dev/null +++ b/src/gui/dialog/dialogloadenvironment.cc @@ -0,0 +1,98 @@ +#include "gepetto/gui/dialog/dialogloadenvironment.hh" +#include "ui_dialogloadenvironment.h" + +#include <QDir> +#include <QMessageBox> +#include <QFileDialog> + +namespace gepetto { + namespace gui { + QList <DialogLoadEnvironment::EnvironmentDefinition> DialogLoadEnvironment::definitions = + QList <DialogLoadEnvironment::EnvironmentDefinition>() + << DialogLoadEnvironment::EnvironmentDefinition (); + + DialogLoadEnvironment::DialogLoadEnvironment(QWidget *parent) : + QDialog(parent), + ui_(new ::Ui::DialogLoadEnvironment) + { + ui_->setupUi(this); + ui_->groupBox_details->setVisible (false); + defs_ = ui_->comboBox_defs; + defs_->setFocus(); + + foreach (EnvironmentDefinition r, definitions) { + defs_->addItem(r.name_, QVariant::fromValue(r)); + } + } + + DialogLoadEnvironment::~DialogLoadEnvironment() + { + delete ui_; + } + + void DialogLoadEnvironment::addEnvironmentDefinition(QString name, QString envName, QString package, QString packagePath, QString urdfFilename, QString urdfSuffix, QString srdfSuffix, QString meshDirectory) + { + definitions.append(EnvironmentDefinition (name, envName, package, packagePath, urdfFilename, urdfSuffix, srdfSuffix, meshDirectory)); + } + + QList<DialogLoadEnvironment::EnvironmentDefinition> DialogLoadEnvironment::getEnvironmentDefinitions() + { + return definitions; + } + + void DialogLoadEnvironment::accept() + { + QDir d (ui_->packagePath->text ()); + if (!d.cd("urdf")) { + QMessageBox (QMessageBox::Warning, "Directory not found", d.absolutePath(), QMessageBox::Ok, this).exec(); + return; + } + if (!d.exists(ui_->urdfFilename->text () + ".urdf")) { + QMessageBox (QMessageBox::Warning, "File not found", d.absoluteFilePath(ui_->urdfFilename->text() + ".urdf"), QMessageBox::Ok, this).exec(); + return; + } + if (!QDir (ui_->meshDirectory->text ()).exists()) { + QMessageBox (QMessageBox::Warning, "File not found", ui_->meshDirectory->text (), QMessageBox::Ok, this).exec(); + return; + } + selected_ = EnvironmentDefinition (defs_->currentText() , + ui_->envName->text(), + ui_->packageName->text(), + ui_->packagePath->text(), + ui_->urdfFilename->text(), + ui_->urdfSuffix->text(), + ui_->srdfSuffix->text(), + ui_->meshDirectory->text()); + done(QDialog::Accepted); + } + + void DialogLoadEnvironment::meshSelect() + { + ui_->meshDirectory->setText( + QFileDialog::getExistingDirectory( + this, "Mesh data directory", ui_->meshDirectory->text())); + } + + void DialogLoadEnvironment::packagePathSelect() + { + QDir path (QFileDialog::getExistingDirectory(this, "Package", ui_->packagePath->text ())); + ui_->packagePath->setText(path.absolutePath()); + ui_->packageName->setText(path.dirName()); + if (ui_->meshDirectory->text().isEmpty()) + ui_->meshDirectory->setText(path.absolutePath()); + } + + void DialogLoadEnvironment::envSelect(int index) + { + QVariant v = defs_->itemData(index); + if (v.canConvert <EnvironmentDefinition>()) { + EnvironmentDefinition rd = v.value <EnvironmentDefinition> (); + ui_->envName->setText(rd.envName_); + ui_->packageName->setText(rd.package_); + ui_->packagePath->setText(rd.packagePath_); + ui_->urdfFilename->setText(rd.urdfFilename_); + ui_->meshDirectory->setText(rd.mesh_); + } + } + } // namespace gui +} // namespace gepetto diff --git a/src/gui/dialog/dialogloadrobot.cc b/src/gui/dialog/dialogloadrobot.cc new file mode 100644 index 0000000..278fe86 --- /dev/null +++ b/src/gui/dialog/dialogloadrobot.cc @@ -0,0 +1,104 @@ +#include "gepetto/gui/dialog/dialogloadrobot.hh" +#include "ui_dialogloadrobot.h" + +#include <QDir> +#include <QMessageBox> +#include <QFileDialog> + +namespace gepetto { + namespace gui { + QStringList DialogLoadRobot::rootJointTypes = QStringList () << "freeflyer" << "planar" << "anchor"; + + QList <DialogLoadRobot::RobotDefinition> DialogLoadRobot::definitions = + QList <DialogLoadRobot::RobotDefinition>() + << DialogLoadRobot::RobotDefinition (); + + DialogLoadRobot::DialogLoadRobot(QWidget *parent) : + QDialog(parent), + ui_(new ::Ui::DialogLoadRobot) + { + ui_->setupUi(this); + ui_->groupBox_details->setVisible (false); + + ui_->rootJointType->addItems (rootJointTypes); + defs_ = ui_->comboBox_defs; + + foreach (RobotDefinition r, definitions) { + defs_->addItem(r.name_, QVariant::fromValue(r)); + } + } + + DialogLoadRobot::~DialogLoadRobot() + { + delete ui_; + } + + void DialogLoadRobot::addRobotDefinition(QString name, QString robotName, QString rootJointType, QString modelName, QString package, QString packagePath, QString urdfSuffix, QString srdfSuffix, QString meshDirectory) + { + definitions.append(RobotDefinition (name, robotName, rootJointType, modelName, package, packagePath, urdfSuffix, srdfSuffix, meshDirectory)); + } + + QList<DialogLoadRobot::RobotDefinition> DialogLoadRobot::getRobotDefinitions() + { + return definitions; + } + + void DialogLoadRobot::accept() + { + QDir d (ui_->packagePath->text ()); + if (!d.cd("urdf")) { + QMessageBox (QMessageBox::Warning, "Directory not found", d.absolutePath(), QMessageBox::Ok, this).exec(); + return; + } + if (!d.exists(ui_->modelName->text () + ui_->urdfSuffix->text () + ".urdf")) { + QMessageBox (QMessageBox::Warning, "File not found", d.absoluteFilePath(ui_->modelName->text () + ui_->urdfSuffix->text () + ".urdf"), QMessageBox::Ok, this).exec(); + return; + } + if (!QDir (ui_->meshDirectory->text ()).exists()) { + QMessageBox (QMessageBox::Warning, "File not found", ui_->meshDirectory->text (), QMessageBox::Ok, this).exec(); + return; + } + selected_ = RobotDefinition (defs_->currentText() , + ui_->robotName->text(), + ui_->rootJointType->currentText(), + ui_->modelName->text(), + ui_->packageName->text(), + ui_->packagePath->text(), + ui_->urdfSuffix->text(), + ui_->srdfSuffix->text(), + ui_->meshDirectory->text()); + done(QDialog::Accepted); + } + + void DialogLoadRobot::packagePathSelect () + { + QDir path (QFileDialog::getExistingDirectory(this, "Package", ui_->packagePath->text ())); + ui_->packagePath->setText(path.absolutePath()); + ui_->packageName->setText(path.dirName()); + if (ui_->meshDirectory->text().isEmpty()) + ui_->meshDirectory->setText(path.absolutePath()); + } + + void DialogLoadRobot::robotSelect(int index) + { + QVariant v = defs_->itemData(index); + if (v.canConvert <RobotDefinition>()) { + RobotDefinition rd = v.value <RobotDefinition> (); + ui_->robotName->setText(rd.robotName_); + ui_->modelName->setText(rd.modelName_); + if (rootJointTypes.contains(rd.rootJointType_)) + ui_->rootJointType->setCurrentIndex (rootJointTypes.indexOf(rd.rootJointType_)); + ui_->packageName->setText(rd.package_); + ui_->packagePath->setText(rd.packagePath_); + ui_->urdfSuffix->setText(rd.urdfSuf_); + ui_->srdfSuffix->setText(rd.srdfSuf_); + ui_->meshDirectory->setText(rd.mesh_); + } + } + + void DialogLoadRobot::meshSelect () + { + ui_->meshDirectory->setText(QFileDialog::getExistingDirectory(this, "Mesh data directory", ui_->meshDirectory->text())); + } + } // namespace gui +} // namespace gepetto diff --git a/src/gui/dialog/pluginmanagerdialog.cc b/src/gui/dialog/pluginmanagerdialog.cc new file mode 100644 index 0000000..3f1f21e --- /dev/null +++ b/src/gui/dialog/pluginmanagerdialog.cc @@ -0,0 +1,184 @@ +#include "gepetto/gui/dialog/pluginmanagerdialog.hh" +#include "ui_pluginmanagerdialog.h" + +#include <QDebug> + +#include "gepetto/gui/plugin-interface.hh" + +#include <iostream> + +namespace gepetto { + namespace gui { + QList <QDir> PluginManager::pluginDirs_; + + bool PluginManager::add(const QString &name, QWidget *parent, bool init) + { + if (!plugins_.contains(name)) { + QString filename = name; + if (!QDir::isAbsolutePath(name)) { + foreach (QDir dir, pluginDirs_) { + if (dir.exists(name)) { + filename = dir.absoluteFilePath(name); + } + } + } + plugins_[name] = new QPluginLoader (filename, parent); + } + if (!plugins_[name]->load()) { + qDebug() << name << ": " << plugins_[name]->errorString(); + return false; + } + if (init) return initPlugin(name); + return false; + } + + QIcon PluginManager::icon(const QPluginLoader *pl) + { + if (pl->isLoaded()) { + const PluginInterface* pi = const_instance_cast <PluginInterface> (pl); + if (pi && pi->isInit ()) { + return QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation); + } + } + return QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical); + } + + QString PluginManager::status(const QPluginLoader *pl) + { + if (pl->isLoaded()) { + const PluginInterface* pi = const_instance_cast <PluginInterface> (pl); + if (pi) { + if (pi->isInit ()) + return QString ("Plugin loaded correctly"); + else + return pi->errorMsg (); + } else + return QString ("Wrong interface"); + } else + return pl->errorString(); + } + + void PluginManager::addPluginDir(const QString &path) + { + QDir dir (QDir::cleanPath(path)); + QDir can (dir.canonicalPath()); + if (can.exists() && can.isReadable()) + { + pluginDirs_.append (can); + } + } + + bool PluginManager::initPlugin(const QString &name) + { + if (!plugins_[name]->isLoaded()) { + qDebug() << name << ": " << plugins_[name]->errorString(); + return false; + } + PluginInterface* pi = qobject_cast <PluginInterface*> (plugins_[name]->instance()); + if (!pi) { + qDebug() << name << ": Wrong interface."; + return false; + } + pi->doInit(); + return pi->isInit (); + } + + bool PluginManager::unloadPlugin(const QString &name) + { + return plugins_[name]->unload(); + } + + PluginManagerDialog::PluginManagerDialog(PluginManager *pm, QWidget *parent) : + QDialog(parent), + ui_(new ::Ui::PluginManagerDialog), + pm_ (pm) + { + ui_->setupUi(this); + + updateList (); + + ui_->pluginList->setColumnHidden(FILE, true); + + connect(ui_->pluginList, SIGNAL (currentItemChanged (QTableWidgetItem*,QTableWidgetItem*)), + this, SLOT (onItemChanged(QTableWidgetItem*,QTableWidgetItem*))); + connect(ui_->pluginList, SIGNAL(customContextMenuRequested(QPoint)), + this, SLOT(contextMenu(QPoint))); + } + + PluginManagerDialog::~PluginManagerDialog() + { + delete ui_; + } + + void PluginManagerDialog::onItemChanged(QTableWidgetItem *current, + QTableWidgetItem */*previous*/) + { + if (!current) return; + QString key = ui_->pluginList->item(current->row(), FILE)->text(); + const QPluginLoader* pl = pm_->plugins()[key]; + ui_->pluginMessage->setText(pm_->status (pl)); + } + + void PluginManagerDialog::contextMenu(const QPoint &pos) + { + int row = ui_->pluginList->rowAt(pos.y()); + if (row == -1) return; + QString key = ui_->pluginList->item(row, FILE)->text(); + QMenu contextMenu (tr("Plugin"), ui_->pluginList); + if (pm_->plugins()[key]->isLoaded()) { + QAction* unload = contextMenu.addAction("&Unload", &signalMapper_, SLOT(map())); + signalMapper_.setMapping (unload, key); + connect(&signalMapper_, SIGNAL (mapped(QString)), this, SLOT(unload(QString))); + contextMenu.exec(ui_->pluginList->mapToGlobal(pos)); + } else { + QAction* load = contextMenu.addAction("&Load", &signalMapper_, SLOT(map())); + signalMapper_.setMapping (load, key); + connect(&signalMapper_, SIGNAL (mapped(QString)), this, SLOT(load(QString))); + contextMenu.exec(ui_->pluginList->mapToGlobal(pos)); + } + } + + void PluginManagerDialog::load(const QString &name) + { + pm_->initPlugin(name); + updateList (); + } + + void PluginManagerDialog::unload(const QString &name) + { + pm_->unloadPlugin (name); + updateList (); + } + + const std::size_t PluginManagerDialog::NAME = 0; + const std::size_t PluginManagerDialog::FILE = 1; + const std::size_t PluginManagerDialog::VERSION = 2; + const std::size_t PluginManagerDialog::FULLPATH = 3; + + void PluginManagerDialog::updateList() + { + while (ui_->pluginList->rowCount() > 0) + ui_->pluginList->removeRow(0); + for (PluginManager::Map::const_iterator p = pm_->plugins ().constBegin(); + p != pm_->plugins().constEnd(); p++) { + QString name = p.value()->fileName(), + filename = p.key(), + fullpath = p.value()->fileName(), + version = ""; + if (p.value ()->isLoaded ()) { + PluginInterface* pi = qobject_cast <PluginInterface*> (p.value()->instance()); + name = pi->name(); + // version = pi->version(); + } + QIcon icon = pm_->icon (p.value()); + + ui_->pluginList->insertRow(ui_->pluginList->rowCount()); + ui_->pluginList->setItem(ui_->pluginList->rowCount() - 1, NAME, new QTableWidgetItem (icon, name)); + ui_->pluginList->setItem(ui_->pluginList->rowCount() - 1, FILE, new QTableWidgetItem (filename)); + ui_->pluginList->setItem(ui_->pluginList->rowCount() - 1, VERSION, new QTableWidgetItem (version)); + ui_->pluginList->setItem(ui_->pluginList->rowCount() - 1, FULLPATH, new QTableWidgetItem (fullpath)); + } + ui_->pluginList->resizeColumnsToContents(); + } + } // namespace gui +} // namespace gepetto diff --git a/src/gui/gepetto-gui.in b/src/gui/gepetto-gui.in new file mode 100644 index 0000000..32f264e --- /dev/null +++ b/src/gui/gepetto-gui.in @@ -0,0 +1,7 @@ +#!/bin/sh + +INSTALL_DIR="@CMAKE_INSTALL_PREFIX@" +export LD_LIBRARY_PATH="${INSTALL_DIR}/lib/gepetto-gui-plugins:$LD_LIBRARY_PATH" +export GEPETTO_GUI_SETTINGS_DIR="${INSTALL_DIR}/etc" + +${INSTALL_DIR}/lib/gepetto-gui $@ diff --git a/src/gui/ledindicator.cc b/src/gui/ledindicator.cc new file mode 100644 index 0000000..7a56f2f --- /dev/null +++ b/src/gui/ledindicator.cc @@ -0,0 +1,40 @@ +#include "gepetto/gui/ledindicator.hh" + +#include <QPainter> +#include <QPalette> +#include <QColor> +#include <QMouseEvent> + +namespace gepetto { + namespace gui { + LedIndicator::LedIndicator(QWidget *parent): + QWidget(parent), + width(28), height(12) { + setFixedSize(width, height); + lit = false; + } + + void LedIndicator::paintEvent(QPaintEvent *) { + QPainter p(this); + p.fillRect(0,0,width,height,lit?Qt::green:Qt::red); + } + + void LedIndicator::mouseReleaseEvent(QMouseEvent *event) + { + if (event->button() == Qt::LeftButton) { + emit mouseClickEvent (); + } + } + + void LedIndicator::switchLed() { + lit = ! lit; + repaint(); + emit switched(lit); + } + + void LedIndicator::switchLed(bool on) { + if (lit == on) return; + switchLed(); + } + } // namespace gui +} // namespace gepetto diff --git a/src/gui/main.cc.in b/src/gui/main.cc.in new file mode 100644 index 0000000..e710f84 --- /dev/null +++ b/src/gui/main.cc.in @@ -0,0 +1,91 @@ +#include <QtGui/QApplication> +#include <QSettings> +#include <QCleanlooksStyle> +#include <QProcessEnvironment> +#include <QSplashScreen> + +#include "gepetto/gui/safeapplication.hh" +#include "gepetto/gui/mainwindow.hh" +#include "gepetto/gui/dialog/pluginmanagerdialog.hh" +#include "gepetto/gui/settings.hh" + +#include <X11/Xlib.h> + +using namespace gepetto::gui; + +void setupEnvironment () +{ + QCoreApplication::setOrganizationName("gepetto-gui"); + QCoreApplication::setOrganizationDomain("https://github.com/jmirabel/gepetto-viewer-corba"); + QCoreApplication::setApplicationName("gepetto-gui"); + QCoreApplication::setApplicationVersion("@PROJECT_VERSION@"); + + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + if (env.contains ("GEPETTO_GUI_SETTINGS_DIR")) { + QSettings::setPath(QSettings::IniFormat, + QSettings::SystemScope, env.value("GEPETTO_GUI_SETTINGS_DIR")); + QSettings::setPath(QSettings::NativeFormat, + QSettings::SystemScope, env.value("GEPETTO_GUI_SETTINGS_DIR")); + } else { + QSettings::setPath(QSettings::IniFormat, + QSettings::SystemScope, "@CMAKE_INSTALL_PREFIX@/etc"); + QSettings::setPath(QSettings::NativeFormat, + QSettings::SystemScope, "@CMAKE_INSTALL_PREFIX@/etc"); + } + + foreach (QString p, env.value("LD_LIBRARY_PATH").split(':')) { + PluginManager::addPluginDir (p + "/gepetto-gui-plugins"); + } + // Finally, add all the folders contained in the folder "plugins" + // in the executable directory. This is convenient for developpers. When + // running "hpp-gui" from the build directory, the current build plugins are + // loaded instead of the installed versions. + // Thus, they do not have to be installed before launching the GUI. + // TODO: A better way to achieve this would be to use environment variables. + QDir here (QCoreApplication::applicationDirPath ()); + here.cd ("plugins"); + if (here.exists () && here.isReadable ()) { + foreach (QString dir, here.entryList (QDir::AllDirs)) { + PluginManager::addPluginDir (here.absoluteFilePath(dir)); + } + } + + QIcon::setThemeName("oxygen"); +} + +int main(int argc, char *argv[]) +{ + XInitThreads(); + + SafeApplication a(argc, argv); + a.setStyle(new QCleanlooksStyle); + + setupEnvironment(); + + Settings settings; + switch (settings.fromArgv (argc, argv)) { + case 0: + break; + case 1: + return 0; + case 2: + return 1; + default: + qDebug () << "Settings.fromArgv returned unknow error code"; + break; + } + settings.fromFiles (); + + QPixmap pixmap(":/img/gepetto.png"); + QSplashScreen splash(pixmap); + splash.show(); + a.processEvents (); + + MainWindow w (&settings); + settings.setMainWindow (&w); + settings.initPlugins (); + w.connect (&a, SIGNAL (log(QString)), SLOT (logError(const QString&))); + w.show(); + splash.finish(&w); + return a.exec(); +} diff --git a/src/gui/mainwindow.cc b/src/gui/mainwindow.cc new file mode 100644 index 0000000..f994da7 --- /dev/null +++ b/src/gui/mainwindow.cc @@ -0,0 +1,421 @@ +#include "gepetto/gui/mainwindow.hh" +#include "ui_mainwindow.h" + +#include <gepetto/viewer/corba/server.hh> + +#include "gepetto/gui/windows-manager.hh" +#include "gepetto/gui/osgwidget.hh" +#include "gepetto/gui/tree-item.hh" +#include "gepetto/gui/dialog/dialogloadrobot.hh" +#include "gepetto/gui/dialog/dialogloadenvironment.hh" +#include "gepetto/gui/plugin-interface.hh" + +#include <gepetto/gui/meta.hh> + +#if GEPETTO_GUI_HAS_PYTHONQT +# include <gepetto/gui/pythonwidget.hh> +#endif + +namespace gepetto { + namespace gui { + MainWindow* MainWindow::instance_ = NULL; + + MainWindow::MainWindow(Settings* settings, QWidget *parent) : + QMainWindow(parent), + settings_ (settings), + ui_(new ::Ui::MainWindow), + centralWidget_ (), + osgViewerManagers_ (WindowsManager::create()), + osgServer_ (NULL), + backgroundQueue_(), + worker_ () + { + MainWindow::instance_ = this; + ui_->setupUi(this); + + if (settings_->startGepettoCorbaServer) { + osgServer_ = new CorbaServer (new ViewerServerProcess ( + new graphics::corbaServer::Server ( + osgViewerManagers_, 0, NULL, true))); + osgServer_->start(); + } + // This scene contains elements required for User Interaction. + osg()->createScene("hpp-gui"); + + // Setup the body tree view + ui_->bodyTreeContent->init(ui_->bodyTree, ui_->toolBox); + + // Setup the main OSG widget + connect (this, SIGNAL (createView(QString)), SLOT (onCreateView(QString))); + + connect (ui_->actionRefresh, SIGNAL (triggered()), SLOT (requestRefresh())); + + connect (&backgroundQueue_, SIGNAL (done(int)), this, SLOT (handleWorkerDone(int))); + connect (&backgroundQueue_, SIGNAL (failed(int,const QString&)), + this, SLOT (logJobFailed(int, const QString&))); + connect (this, SIGNAL (sendToBackground(WorkItem*)), + &backgroundQueue_, SLOT (perform(WorkItem*))); + backgroundQueue_.moveToThread(&worker_); + worker_.start(); + + setupInterface(); +#if GEPETTO_GUI_HAS_PYTHONQT + pythonWidget_ = new PythonWidget(this); + insertDockWidget(pythonWidget_, Qt::RightDockWidgetArea, Qt::Horizontal); +#endif + } + + MainWindow::~MainWindow() + { + osgViewerManagers_.reset(); + worker_.quit(); + if (osgServer_ != NULL) { + osgServer_->wait(); + delete osgServer_; + } + worker_.wait(); + delete ui_; + } + + MainWindow *MainWindow::instance() + { + return instance_; + } + + void MainWindow::insertDockWidget(QDockWidget *dock, Qt::DockWidgetArea area, Qt::Orientation orientation) + { + addDockWidget(area, dock, orientation); + dock->setVisible (false); + dock->toggleViewAction ()->setIcon(QIcon::fromTheme("window-new")); + dock->adjustSize(); + ui_->menuWindow->addAction(dock->toggleViewAction ()); + } + + void MainWindow::removeDockWidget(QDockWidget *dock) + { + ui_->menuWindow->removeAction(dock->toggleViewAction()); + QMainWindow::removeDockWidget(dock); + } + + BackgroundQueue& MainWindow::worker() + { + return backgroundQueue_; + } + + WindowsManagerPtr_t MainWindow::osg() const + { + return osgViewerManagers_; + } + + OSGWidget *MainWindow::centralWidget() const + { + return centralWidget_; + } + + BodyTreeWidget *MainWindow::bodyTree() const + { + return ui_->bodyTreeContent; + } + + QList<OSGWidget *> MainWindow::osgWindows() const + { + return osgWindows_; + } + + PluginManager *MainWindow::pluginManager() + { + return &(settings_->pluginManager_); + } + + void MainWindow::log(const QString &text) + { + ui_->logText->insertHtml("<hr/><font color=black>"+text+"</font>"); + } + + void MainWindow::logError(const QString &text) + { + if (!ui_->dockWidget_log->isVisible()) { + ui_->dockWidget_log->show(); + } + QScrollBar* sb = ui_->logText->verticalScrollBar(); + bool SBwasAtBottom = sb->value() == sb->maximum(); + ui_->logText->insertHtml("<hr/><font color=red>"+text+"</font>"); + if (SBwasAtBottom) + sb->setValue(sb->maximum()); + } + + void MainWindow::emitSendToBackground(WorkItem *item) + { + emit sendToBackground(item); + } + + void MainWindow::logJobStarted(int id, const QString &text) + { + log (QString ("Starting job ") + QString::number (id) + ": " + text); + } + + void MainWindow::logJobDone(int id, const QString &text) + { + log (QString ("Job ") + QString::number (id) + " done: " + text); + } + + void MainWindow::logJobFailed(int id, const QString &text) + { + logError (QString ("Job ") + QString::number (id) + " failed: " + text); + } + + OSGWidget *MainWindow::delayedCreateView(QString name) + { + delayedCreateView_.lock(); + emit createView(name); + delayedCreateView_.lock(); + delayedCreateView_.unlock(); + return osgWindows_.last(); + } + + void MainWindow::requestRefresh() + { + emit refresh (); + } + + OSGWidget *MainWindow::onCreateView() { + return onCreateView ("hpp_gui_window_" + QString::number(osgWindows_.size())); + } + + OSGWidget *MainWindow::onCreateView(QString objName) + { + OSGWidget* osgWidget = new OSGWidget (osgViewerManagers_, objName.toStdString(), + this, 0); + if (!osgWindows_.empty()) { + QDockWidget* dockOSG = new QDockWidget ( + tr("OSG Viewer") + " " + QString::number (osgWindows_.size()), this); + osgWidget->setObjectName(objName); + dockOSG->setWidget(osgWidget); + addDockWidget(Qt::RightDockWidgetArea, dockOSG); + } else { + // This OSGWidget should be the central view + centralWidget_ = osgWidget; + centralWidget_->setObjectName(objName); + setCentralWidget(centralWidget_); + #if PYTHONQT_NEED_INCLUDE==1 + pythonWidget_->addToContext("osg", centralWidget_); + #endif + connect(ui_->actionHome, SIGNAL (triggered()), centralWidget_, SLOT (onHome())); + connect(ui_->actionSelection, SIGNAL (triggered()), centralWidget_, SLOT (selectionMode())); + connect(ui_->actionCamera_control_mode, SIGNAL (triggered()), centralWidget_, SLOT (cameraManipulationMode())); + ui_->osgToolBar->show(); + + osg()->addSceneToWindow("hpp-gui", centralWidget_->windowID()); + connect(ui_->actionAdd_floor, SIGNAL (triggered()), centralWidget_, SLOT (addFloor())); + } + osgWindows_.append(osgWidget); + delayedCreateView_.unlock(); + return osgWidget; + } + + void MainWindow::openLoadRobotDialog() + { + statusBar()->showMessage("Loading a robot..."); + DialogLoadRobot* d = new DialogLoadRobot (this); + if (d->exec () == QDialog::Accepted) { + createCentralWidget(); + DialogLoadRobot::RobotDefinition rd = d->getSelectedRobotDescription(); + + QDir dir (rd.packagePath_); dir.cd("urdf"); + QString urdfFile = dir.absoluteFilePath(rd.modelName_ + rd.urdfSuf_ + ".urdf"); + try { + centralWidget_->loadURDF(rd.robotName_, urdfFile, rd.mesh_); + } catch (std::runtime_error& exc) { + logError (exc.what ()); + } + robotNames_.append (rd.robotName_); + + QString what = QString ("Loading robot ") + rd.name_; + WorkItem* item; + foreach (ModelInterface* loader, pluginManager()->get <ModelInterface> ()) { + item = new WorkItem_1 <ModelInterface, void, + DialogLoadRobot::RobotDefinition> + (loader, &ModelInterface::loadRobotModel, rd); + logJobStarted(item->id(), what); + emit sendToBackground(item); + } + } + d->close(); + statusBar()->clearMessage(); + d->deleteLater(); + } + + void MainWindow::openLoadEnvironmentDialog() + { + statusBar()->showMessage("Loading an environment..."); + DialogLoadEnvironment* e = new DialogLoadEnvironment (this); + if (e->exec() == QDialog::Accepted) { + createCentralWidget(); + DialogLoadEnvironment::EnvironmentDefinition ed = e->getSelectedDescription(); + + QDir d (ed.packagePath_); d.cd("urdf"); + QString urdfFile = d.absoluteFilePath(ed.urdfFilename_ + ".urdf"); + try { + osgViewerManagers_->addUrdfObjects( + Traits<QString>::to_corba(ed.envName_).in(), + Traits<QString>::to_corba(urdfFile ).in(), + Traits<QString>::to_corba(ed.mesh_ ).in(), + true); + osgViewerManagers_->addSceneToWindow( + Traits<QString>::to_corba(ed.envName_).in(), + centralWidget_->windowID()); + } catch (std::runtime_error& exc) { + log (exc.what ()); + } + bodyTree()->addBodyToTree(osgViewerManagers_->getScene(ed.envName_.toStdString())); + + QString what = QString ("Loading environment ") + ed.name_; + WorkItem* item; + foreach (ModelInterface* loader, pluginManager()->get <ModelInterface> ()) { + item = new WorkItem_1 <ModelInterface, void, + DialogLoadEnvironment::EnvironmentDefinition> + (loader, &ModelInterface::loadEnvironmentModel, ed); + logJobStarted(item->id(), what); + emit sendToBackground(item); + } + } + statusBar()->clearMessage(); + e->close(); + e->deleteLater(); + } + + void MainWindow::handleWorkerDone(int /*id*/) + { + } + + void MainWindow::resetConnection() + { + foreach (CorbaInterface* e, pluginManager()->get <CorbaInterface> ()) { + e->openConnection (); + } + } + + void MainWindow::about() + { + QString devString; + devString = trUtf8("<p>Version %1. For more information visit <a href=\"%2\">%3</a></p>" + "<p><small>Copyright (c) 2015 CNRS<br/>By Joseph Mirabel and others.</small></p>" + "<p><small>" + "hpp-gui is free software: you can redistribute it and/or modify it under the " + "terms of the GNU Lesser General Public License as published by the Free " + "Software Foundation, either version 3 of the License, or (at your option) " + "any later version.<br/><br/>" + "hpp-gui is distributed in the hope that it will be " + "useful, but WITHOUT ANY WARRANTY; without even the implied warranty " + "of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU " + "General Lesser Public License for more details. You should have " + "received a copy of the GNU Lesser General Public License along with hpp-gui." + "If not, see <a href=\"http://www.gnu.org/licenses\">http://www.gnu.org/licenses<a/>." + "</small></p>" + ) + .arg(QApplication::applicationVersion()) + .arg(QApplication::organizationDomain()) + .arg(QApplication::organizationDomain()); + + QMessageBox::about(this, QApplication::applicationName(), devString); + } + + void MainWindow::setupInterface() + { + // Menu "Window" + QMenu* toolbar = ui_->menuWindow->addMenu("Tool bar"); + toolbar->setIcon(QIcon::fromTheme("configure-toolbars")); + ui_->mainToolBar->setVisible(true); + ui_->osgToolBar->setVisible(false); + toolbar->addAction (ui_->mainToolBar->toggleViewAction ()); + toolbar->addAction (ui_->osgToolBar->toggleViewAction ()); + + ui_->menuWindow->addSeparator(); + + ui_->dockWidget_bodyTree->setVisible (false); + ui_->dockWidget_bodyTree->toggleViewAction ()->setIcon(QIcon::fromTheme("window-new")); + ui_->dockWidget_bodyTree->toggleViewAction ()->setShortcut(Qt::CTRL + Qt::ALT + Qt::Key_B); + ui_->menuWindow->addAction(ui_->dockWidget_bodyTree->toggleViewAction ()); + ui_->dockWidget_log->setVisible (false); + ui_->dockWidget_log->toggleViewAction ()->setIcon(QIcon::fromTheme("window-new")); + ui_->dockWidget_log->toggleViewAction ()->setShortcut(Qt::CTRL + Qt::ALT + Qt::Key_L); + ui_->menuWindow->addAction(ui_->dockWidget_log->toggleViewAction ()); + + ui_->menuWindow->addSeparator(); + + // Setup the status bar + collisionIndicator_ = new LedIndicator (statusBar()); + collisionValidationActivated_ = new QCheckBox (); + collisionValidationActivated_->setToolTip (tr("Automatically validate configurations.")); + collisionValidationActivated_->setCheckState (Qt::Checked); + statusBar()->addPermanentWidget(collisionValidationActivated_); + statusBar()->addPermanentWidget(collisionIndicator_); + + connect (collisionIndicator_, SIGNAL (mouseClickEvent()), SLOT(requestConfigurationValidation())); + connect (ui_->actionAbout, SIGNAL (triggered ()), SLOT(about())); + connect (ui_->actionReconnect, SIGNAL (triggered ()), SLOT(resetConnection())); + connect (ui_->actionFetch_configuration, SIGNAL (triggered ()), SLOT(requestApplyCurrentConfiguration())); + } + + void MainWindow::createCentralWidget() + { + if (!osgWindows_.empty()) return; + onCreateView(); + } + + void MainWindow::requestApplyCurrentConfiguration() + { + emit applyCurrentConfiguration(); + if (collisionValidationActivated_->isChecked ()) + requestConfigurationValidation(); + } + + void MainWindow::requestConfigurationValidation() + { + emit configurationValidation(); + } + + void MainWindow::onOpenPluginManager() + { + PluginManagerDialog d (pluginManager(), this); + d.exec (); + } + + void MainWindow::configurationValidationStatusChanged (bool valid) + { + collisionIndicator_->switchLed (valid); + int state = (valid)?0:1; + foreach(const QString& s, robotNames_) { + osg ()->setHighlight(s.toLocal8Bit().data(), state); + } + } + + void MainWindow::configurationValidationStatusChanged (QStringList bodiesInCollision) + { + QStringList lastBodiesInCollision = lastBodiesInCollision_; + lastBodiesInCollision_.clear(); + collisionIndicator_->switchLed (bodiesInCollision.empty()); + foreach (QString b, lastBodiesInCollision) { + if (bodiesInCollision.removeAll(b) == 0) { + /// This body is not in collision + osg ()->setHighlight(b.toLocal8Bit().data(), 0); + } else { + /// This body is still in collision + lastBodiesInCollision_.append(b); + } + } + QString tooltip ("Collision between "); + tooltip += bodiesInCollision.join (", "); + foreach(const QString& b, bodiesInCollision) { + osg ()->setHighlight(b.toLocal8Bit().data(), 1); + lastBodiesInCollision_.append(b); + } + collisionIndicator_->setToolTip (tooltip); + } + + void MainWindow::requestSelectJointFromBodyName(const QString bodyName) + { + emit selectJointFromBodyName(bodyName); + } + } // namespace gui +} // namespace gepetto diff --git a/src/gui/omniorbthread.cc b/src/gui/omniorbthread.cc new file mode 100644 index 0000000..a2a41ba --- /dev/null +++ b/src/gui/omniorbthread.cc @@ -0,0 +1,130 @@ +#include "gepetto/gui/omniorb/omniorbthread.hh" + +#include <gepetto/viewer/corba/server.hh> +#include <QDebug> + +#include <gepetto/gui/mainwindow.hh> +#include <gepetto/gui/plugin-interface.hh> + +namespace gepetto { + namespace gui { + int WorkItem::idGlobal = 0; + + ServerProcess::ServerProcess() + : initDone_ () + { + initDone_.lock(); + } + + void ServerProcess::waitForInitDone() + { + initDone_.lock(); + initDone_.unlock(); + } + + void ServerProcess::init() + { + initDone_.unlock(); + } + + ViewerServerProcess::ViewerServerProcess (graphics::corbaServer::Server *server) + : server_ (server) + {} + + ViewerServerProcess::~ViewerServerProcess() + { + delete server_; + } + + void ViewerServerProcess::init() + { + server_->startCorbaServer (); + emit done (); + ServerProcess::init(); + } + + void ViewerServerProcess::processRequest(bool loop) + { + server_->processRequest (loop); + emit done(); + } + + CorbaServer::CorbaServer (ServerProcess* process) : + QObject (), control_ (process), worker_ (), timerId_ (-1), interval_ (100) + { + connect (this, SIGNAL (process(bool)), control_, SLOT (processRequest (bool))); + connect (control_, SIGNAL (done()), this, SLOT (processed())); + connect (&worker_, SIGNAL (started()), control_, SLOT (init())); + control_->moveToThread(&worker_); + } + + CorbaServer::~CorbaServer() + { + if (control_) + delete control_; + } + + void CorbaServer::wait () + { + worker_.quit (); + worker_.wait(200); + if (worker_.isRunning()) { + worker_.terminate(); + worker_.wait(); + } + } + + void CorbaServer::waitForInitDone() + { + control_->waitForInitDone(); + } + + void CorbaServer::start() + { + worker_.start(); + } + + void CorbaServer::timerEvent(QTimerEvent* event) + { + Q_UNUSED (event); + assert (event->timerId () == timerId_); + emit process (false); + killTimer(timerId_); + } + + void CorbaServer::processed() + { + timerId_ = startTimer(interval_); + } + + BackgroundQueue::BackgroundQueue(QObject *parent) : + QObject (parent) + { + } + + void BackgroundQueue::perform(WorkItem *item) + { + try { + item->performWork(); + emit done (item->id ()); + } catch (std::exception& e) { + emit failed (item->id(), QString (e.what())); + } catch (const CORBA::Exception& e) { + /// Enable plugins to get corba errors. + /// hpp plugins can thus handle CORBA Exceptions (gepetto::Error) + bool handled = false; + foreach (CorbaInterface* errorHandler, MainWindow::instance()->pluginManager()->get <CorbaInterface>()) { + if (errorHandler->corbaException (item->id(), e)) { + handled = true; + break; + } + } + if (!handled) + emit failed (item->id(), QString ("Unhandled CORBA Exception %1").arg(e._name())); + } catch (...) { + emit failed (item->id(), QString ("Unkown error type")); + } + delete item; + } + } // namespace gui +} // namespace gepetto diff --git a/src/gui/osgwidget.cc b/src/gui/osgwidget.cc new file mode 100644 index 0000000..5737ea4 --- /dev/null +++ b/src/gui/osgwidget.cc @@ -0,0 +1,364 @@ +#include "gepetto/gui/osgwidget.hh" +#include "gepetto/gui/mainwindow.hh" + +#include <boost/regex.hpp> + +#include <osg/Camera> + +#include <osg/DisplaySettings> +#include <osg/Geode> +#include <osg/Material> +#include <osg/Shape> +#include <osg/ShapeDrawable> +#include <osg/StateSet> + +#include <osgGA/EventQueue> +#include <osgGA/KeySwitchMatrixManipulator> +#include <osgGA/TrackballManipulator> + +#include <osgUtil/IntersectionVisitor> +#include <osgUtil/PolytopeIntersector> + +#include <osgViewer/View> +#include <osgViewer/ViewerEventHandlers> + +#include <cassert> + +#include <stdexcept> +#include <vector> + +#include <QDebug> +#include <QKeyEvent> +#include <QWheelEvent> + +#include <gepetto/viewer/urdf-parser.h> +#include <gepetto/viewer/OSGManipulator/keyboard-manipulator.h> + +#include <gepetto/gui/windows-manager.hh> +#include <gepetto/gui/bodytreewidget.hh> +#include <gepetto/gui/pick-handler.hh> + +namespace gepetto { + namespace gui { + namespace + { + + QRect makeRectangle( const QPoint& first, const QPoint& second ) + { + // Relative to the first point, the second point may be in either one of the + // four quadrants of an Euclidean coordinate system. + // + // We enumerate them in counter-clockwise order, starting from the lower-right + // quadrant that corresponds to the default case: + // + // | + // (3) | (4) + // | + // -------|------- + // | + // (2) | (1) + // | + + if( second.x() >= first.x() && second.y() >= first.y() ) + return QRect( first, second ); + else if( second.x() < first.x() && second.y() >= first.y() ) + return QRect( QPoint( second.x(), first.y() ), QPoint( first.x(), second.y() ) ); + else if( second.x() < first.x() && second.y() < first.y() ) + return QRect( second, first ); + else if( second.x() >= first.x() && second.y() < first.y() ) + return QRect( QPoint( first.x(), second.y() ), QPoint( second.x(), first.y() ) ); + + // Should never reach that point... + return QRect(); + } + + } + + OSGWidget::OSGWidget(WindowsManagerPtr_t wm, + std::string name, + MainWindow *parent, Qt::WindowFlags f , + osgViewer::ViewerBase::ThreadingModel threadingModel) + : QWidget( parent, f ) + , graphicsWindow_() + , wsm_ (wm) + , pickHandler_ (new PickHandler (wsm_)) + , wid_ (-1) + , wm_ () + , viewer_ (new osgViewer::Viewer) + , screenCapture_ () + , mode_ (CAMERA_MANIPULATION) + , selectionFinished_( true ) + , infoBox_ (this) + { + osg::DisplaySettings* ds = osg::DisplaySettings::instance().get(); + osg::ref_ptr <osg::GraphicsContext::Traits> traits_ptr (new osg::GraphicsContext::Traits); + traits_ptr->windowName = "Gepetto Viewer"; + traits_ptr->x = this->x(); + traits_ptr->y = this->y(); + traits_ptr->width = this->width(); + traits_ptr->height = this->height(); + traits_ptr->windowDecoration = false; + traits_ptr->doubleBuffer = true; + traits_ptr->vsync = true; + // traits_ptr->sharedContext = 0; + // traits_ptr->sampleBuffers = 1; + // traits_ptr->samples = 1; + + traits_ptr->alpha = ds->getMinimumNumAlphaBits(); + traits_ptr->stencil = ds->getMinimumNumStencilBits(); + traits_ptr->sampleBuffers = ds->getMultiSamples(); + traits_ptr->samples = ds->getNumMultiSamples(); + + graphicsWindow_ = new osgQt::GraphicsWindowQt ( traits_ptr ); + + osg::Camera* camera = viewer_->getCamera(); + camera->setGraphicsContext( graphicsWindow_ ); + + camera->setClearColor( osg::Vec4(0.2f, 0.2f, 0.6f, 1.0f) ); + camera->setViewport( new osg::Viewport(0, 0, traits_ptr->width, traits_ptr->height) ); + camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits_ptr->width)/static_cast<double>(traits_ptr->height), 1.0f, 10000.0f ); + + viewer_->setKeyEventSetsDone(0); + + + osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator; + keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() ); + keyswitchManipulator->addMatrixManipulator( '2', "First person", new ::osgGA::KeyboardManipulator(graphicsWindow_)); + keyswitchManipulator->selectMatrixManipulator (0); + viewer_->setCameraManipulator( keyswitchManipulator.get() ); + + screenCapture_ = new osgViewer::ScreenCaptureHandler ( + new osgViewer::ScreenCaptureHandler::WriteToFile ( + parent->settings_->captureDirectory + "/" + parent->settings_->captureFilename, + parent->settings_->captureExtension), + 1); + viewer_->addEventHandler(screenCapture_); + viewer_->addEventHandler(new osgViewer::HelpHandler); + + connect(pickHandler_, SIGNAL(selected(QString)), SLOT(transferSelected(QString))); + viewer_->addEventHandler(pickHandler_); + + wid_ = wm->createWindow (name.c_str(), viewer_, graphicsWindow_.get()); + wm_ = wsm_->getWindowManager (wid_); + + viewer_->setThreadingModel(threadingModel); + + QGLWidget* glWidget = graphicsWindow_->getGLWidget(); + QHBoxLayout* hblayout = new QHBoxLayout (this); + hblayout->setContentsMargins(1,1,1,1); + setLayout (hblayout); + hblayout->addWidget(glWidget); + + render_.viewerPtr = viewer_; + render_.wsm_ = wsm_; + render_.refreshRate = parent->settings_->refreshRate; + render_.start (); + + parent->bodyTree()->connect(this, + SIGNAL (selected(QString)), SLOT (selectBodyByName(QString))); + parent->connect(this, SIGNAL (selected(QString)), + SLOT (requestSelectJointFromBodyName(QString))); + } + + OSGWidget::~OSGWidget() + { + viewer_->setDone(true); + viewer_->removeEventHandler(pickHandler_); + pickHandler_ = NULL; + wm_.reset(); + wsm_.reset(); + } + + graphics::WindowsManager::WindowID OSGWidget::windowID() const + { + return wid_; + } + + void OSGWidget::loadURDF(const QString robotName, + const QString urdf_file_path, + const QString meshDataRootDir) + { + QByteArray rn = robotName.toLocal8Bit(); + QByteArray uf = urdf_file_path.toLocal8Bit(); + QByteArray md = meshDataRootDir.toLocal8Bit(); + wsm_->addURDF(rn.constData(), + uf.constData(), + md.constData()); + wsm_->addSceneToWindow(rn.constData(), wid_); + MainWindow* w = dynamic_cast <MainWindow*> (parentWidget()); + if (w) { + w->bodyTree()->addBodyToTree (wsm_->getScene (robotName.toStdString())); + } + } + + void OSGWidget::paintEvent( QPaintEvent* /* paintEvent */ ) + { +// wsm_->lock().lock(); +// viewer_->frame(); + // wsm_->lock().unlock(); + } + + void gepetto::gui::OSGWidget::transferSelected(QString name) + { + emit selected (name); + } + + void OSGWidget::onHome() + { + viewer_->home (); + } + + void OSGWidget::changeMode(Mode mode) + { + mode_ = mode; + infoBox_.setMode (mode); + } + + void OSGWidget::selectionMode() + { + mode_ = NODE_SELECTION; + infoBox_.setMode(NODE_SELECTION); + } + + void OSGWidget::cameraManipulationMode() + { + mode_ = CAMERA_MANIPULATION; + infoBox_.setMode(CAMERA_MANIPULATION); + } + + void OSGWidget::addFloor() + { + wsm_->addFloor("hpp-gui/floor"); + } + + void OSGWidget::attachToWindow(const std::string nodeName) + { + wsm_->addSceneToWindow(nodeName.c_str(), wid_); + } + + osgGA::EventQueue* OSGWidget::getEventQueue() const + { + osgGA::EventQueue* eventQueue = viewer_->getEventQueue(); + + if( eventQueue ) + return( eventQueue ); + else + throw( std::runtime_error( "Unable to obtain valid event queue") ); + } + + std::list <graphics::NodePtr_t> OSGWidget::processSelection() + { + NodeList nodes; + QRect selectionRectangle = makeRectangle( selectionStart_, selectionEnd_ ); + int widgetHeight = this->height(); + + double xMin = selectionRectangle.left(); + double xMax = selectionRectangle.right(); + double yMin = widgetHeight - selectionRectangle.bottom(); + double yMax = widgetHeight - selectionRectangle.top(); + + osg::ref_ptr<osgUtil::PolytopeIntersector> polytopeIntersector + = new osgUtil::PolytopeIntersector( osgUtil::PolytopeIntersector::WINDOW, + xMin, yMin, + xMax, yMax ); + + // This limits the amount of intersections that are reported by the + // polytope intersector. Using this setting, a single drawable will + // appear at most once while calculating intersections. This is the + // preferred and expected behaviour. + polytopeIntersector->setIntersectionLimit( osgUtil::Intersector::LIMIT_ONE_PER_DRAWABLE ); + + osgUtil::IntersectionVisitor iv( polytopeIntersector ); + + osg::ref_ptr<osg::Camera> camera = viewer_->getCamera(); + + if( !camera ) + throw std::runtime_error( "Unable to obtain valid camera for selection processing" ); + + camera->accept( iv ); + + if( !polytopeIntersector->containsIntersections() ) + return nodes; + + osgUtil::PolytopeIntersector::Intersections intersections = polytopeIntersector->getIntersections(); + + for(osgUtil::PolytopeIntersector::Intersections::iterator it = intersections.begin(); + it != intersections.end(); ++it) { + for (int i = (int) it->nodePath.size()-1; i >= 0 ; --i) { + graphics::NodePtr_t n = wsm_->getNode(it->nodePath[i]->getName ()); + if (n) { + if (boost::regex_match (n->getID().c_str(), boost::regex ("^.*_[0-9]+$"))) + continue; + nodes.push_back(n); + break; + } + } + } + return nodes; + } + + OSGWidget::InfoBox::InfoBox(QWidget *parent) : + size_ (16,16), + selection_ (QIcon::fromTheme("edit-select").pixmap(size_)), + record_ (QIcon::fromTheme("media-record").pixmap(size_)), + label_ (new QLabel (parent)) + { + label_->setAutoFillBackground(true); + label_->hide(); + label_->setGeometry(QRect (QPoint(0,0), size_)); + } + + void OSGWidget::InfoBox::normalMode() + { + label_->hide(); + } + + void OSGWidget::InfoBox::selectionMode() + { + label_->show(); + label_->setPixmap(selection_); + } + + void OSGWidget::InfoBox::recordMode() + { + label_->show(); + label_->setPixmap(record_); + } + + void OSGWidget::InfoBox::setMode(OSGWidget::Mode mode) + { + switch (mode) { + case CAMERA_MANIPULATION: + normalMode(); + break; + case NODE_SELECTION: + selectionMode(); + break; + case NODE_MOTION: + selectionMode(); + break; + default: + normalMode(); + break; + } + } + + void RenderThread::run() + { + if (viewerPtr) { + while (!viewerPtr->done ()) { + wsm_->lock ().lock(); + viewerPtr->frame(); + wsm_->lock ().unlock(); + QThread::msleep(30); + } + } + } + + RenderThread::~RenderThread() { + if (viewerPtr) viewerPtr->setDone(true); + wait(); + } + + } // namespace gui +} // namespace gepetto diff --git a/src/gui/pick-handler.cc b/src/gui/pick-handler.cc new file mode 100644 index 0000000..13e25f2 --- /dev/null +++ b/src/gui/pick-handler.cc @@ -0,0 +1,180 @@ +#include "gepetto/gui/pick-handler.hh" + +#include <QDebug> + +#include <osg/io_utils> + +#include <osgUtil/IntersectionVisitor> +#include <osgUtil/LineSegmentIntersector> + +#include <osgViewer/Viewer> + +#include <iostream> +#include <boost/regex.hpp> + +#include <gepetto/gui/windows-manager.hh> +#include <gepetto/gui/osgwidget.hh> +#include <gepetto/gui/mainwindow.hh> +#include <gepetto/gui/bodytreewidget.hh> +#include <gepetto/gui/tree-item.hh> + +namespace gepetto { + namespace gui { + PickHandler::PickHandler(WindowsManagerPtr_t wsm) + : wsm_ (wsm) + , last_ () + , pushed_ (false) + , lastX_ (0) + , lastY_ (0) + { + MainWindow* main = MainWindow::instance (); + connect (main->bodyTree ()->view ()->selectionModel(), + SIGNAL (currentChanged(QModelIndex,QModelIndex)), + SLOT (bodyTreeCurrentChanged(QModelIndex,QModelIndex))); + } + + PickHandler::~PickHandler() + { + } + + bool PickHandler::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa ) + { + switch (ea.getEventType()) { + case osgGA::GUIEventAdapter::PUSH: + case osgGA::GUIEventAdapter::RELEASE: + if (ea.getButton() == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON) { + if (pushed_ + && ea.getEventType() == osgGA::GUIEventAdapter::RELEASE) { + pushed_ = false; + if ((int)floor(lastX_ - ea.getX()+0.05) == 0 + && (int)floor(lastY_ - ea.getY() + 0.5) == 0) { + computeIntersection(aa, ea.getX(), ea.getY()); + return true; + } + } + if (ea.getEventType() == osgGA::GUIEventAdapter::PUSH) { + lastX_ = ea.getX(); + lastY_ = ea.getY(); + pushed_ = true; + } + } + return false; + break; + case osgGA::GUIEventAdapter::KEYUP: + switch (ea.getKey ()) { + case 'z': + setCameraToSelected (aa, false); + return true; + case 'Z': + setCameraToSelected (aa, true); + return true; + default: + break; + } + break; + default: + break; + } + return false; + } + + void PickHandler::select (graphics::NodePtr_t node) + { + if (last_ == node) return; + if (last_) last_->setHighlightState (0); + last_ = node; + if (last_) last_->setHighlightState (8); + } + + void PickHandler::getUsage (osg::ApplicationUsage& usage) + { + usage.addKeyboardMouseBinding ("Right click", "Select node"); + usage.addKeyboardMouseBinding ('z', "Move camera on selected node"); + usage.addKeyboardMouseBinding ('Z', "Move and zoom on selected node"); + } + + std::list<graphics::NodePtr_t> PickHandler::computeIntersection(osgGA::GUIActionAdapter &aa, + const float &x, const float &y) + { + std::list<graphics::NodePtr_t> nodes; + osgViewer::View* viewer = dynamic_cast<osgViewer::View*>( &aa ); + if( viewer ) + { + // There is no need to lock the windows manager mutex + // as this is treated in the event loop of OSG, and not Qt. + // On the contrary, locking here creates a deadlock as the lock is + // already acquired by OSGWidget::paintEvent. + // wsm_->lock().lock(); + osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = + new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y); + intersector->setIntersectionLimit( osgUtil::Intersector::LIMIT_ONE_PER_DRAWABLE ); + + osgUtil::IntersectionVisitor iv( intersector ); + + osg::Camera* camera = viewer->getCamera(); + + camera->accept( iv ); + + if( !intersector->containsIntersections() ) { + select (graphics::NodePtr_t()); + return nodes; + } + + osgUtil::LineSegmentIntersector::Intersections intersections = intersector->getIntersections(); + + for(osgUtil::LineSegmentIntersector::Intersections::iterator it = intersections.begin(); + it != intersections.end(); ++it) { + for (int i = (int) it->nodePath.size()-1; i >= 0 ; --i) { + graphics::NodePtr_t n = wsm_->getNode(it->nodePath[i]->getName ()); + if (n) { + if (boost::regex_match (n->getID(), boost::regex ("^.*_[0-9]+$"))) + continue; + select (n); + emit selected (QString::fromStdString(n->getID ())); + return nodes; + // nodes.push_back(n); + // break; + } + } + } + // emit parent_->selected (nodes.front()->getID ()); + } + select (graphics::NodePtr_t()); + return nodes; + } + + void PickHandler::setCameraToSelected (osgGA::GUIActionAdapter &aa, + bool zoom) + { + if (!last_) return; + osgViewer::View* viewer = dynamic_cast<osgViewer::View*>( &aa ); + if(!viewer) return; + + const osg::BoundingSphere& bs = last_->asGroup()->getBound (); + osg::Vec3f eye, center, up; + viewer->getCameraManipulator()->getInverseMatrix () + .getLookAt (eye, center, up); + if (zoom) { + eye.normalize(); + eye *= 1 + bs.radius (); + } + viewer->getCameraManipulator()->setByInverseMatrix ( + osg::Matrixd::lookAt (eye, bs.center(), up) + ); + } + + void PickHandler::bodyTreeCurrentChanged (const QModelIndex ¤t, + const QModelIndex &/*previous*/) + { + BodyTreeItem *item = dynamic_cast <BodyTreeItem*> ( + qobject_cast <const QStandardItemModel*> + (current.model())->itemFromIndex(current) + ); + if (item) { + wsm_->lock ().lock(); + select (item->node ()); + wsm_->lock ().unlock(); + } + } + } +} diff --git a/src/gui/pythonwidget.cc b/src/gui/pythonwidget.cc new file mode 100644 index 0000000..5ab31df --- /dev/null +++ b/src/gui/pythonwidget.cc @@ -0,0 +1,59 @@ +#include "gepetto/gui/pythonwidget.hh" + +#include <QFileDialog> + +#include "gepetto/gui/osgwidget.hh" +#include "gepetto/gui/mainwindow.hh" + +namespace gepetto { + namespace gui { + PythonWidget::PythonWidget(QWidget *parent) : + QDockWidget("PythonQt console", parent) + { + PythonQt::init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut); + PythonQt_QtAll::init(); + mainContext_ = PythonQt::self()->getMainModule(); + PythonQtObjectPtr sys = PythonQt::self()->importModule ("sys"); + sys.addVariable ("argv", QVariant(QStringList () << "toto.py")); + console_ = new PythonQtScriptingConsole(NULL, mainContext_); + mainContext_.addObject("mainWindow", MainWindow::instance()); + + QWidget* widget = new QWidget; + QVBoxLayout* layout = new QVBoxLayout; + button_ = new QPushButton; + + button_->setText("Choose file"); + layout->addWidget(console_); + layout->addWidget(button_); + widget->setLayout(layout); + this->setWidget(widget); + + connect(button_, SIGNAL(clicked()), SLOT(browseFile())); + } + + PythonWidget::~PythonWidget() + { + std::cout << "begin cleanup" << std::endl; + PythonQt::cleanup(); + std::cout << "end cleanup" << std::endl; + } + + void PythonWidget::browseFile() { + QFileDialog* fd = new QFileDialog; + + fd->setFileMode(QFileDialog::ExistingFile); + fd->setNameFilter("All python file (*.py)"); + if (fd->exec() == QDialog::Accepted) { + QStringList file = fd->selectedFiles(); + + mainContext_.evalFile(file.at(0)); + } + fd->close(); + fd->deleteLater(); + } + + void PythonWidget::addToContext(QString const& name, QObject* obj) { + mainContext_.addObject(name, obj); + } + } +} diff --git a/src/gui/safeapplication.cc b/src/gui/safeapplication.cc new file mode 100644 index 0000000..1f37547 --- /dev/null +++ b/src/gui/safeapplication.cc @@ -0,0 +1,42 @@ +#include "gepetto/gui/safeapplication.hh" + +#include <QDebug> +#include <omniORB4/CORBA.h> +#include <gepetto/gui/mainwindow.hh> +#include <gepetto/gui/plugin-interface.hh> + +namespace gepetto { + namespace gui { + SafeApplication::SafeApplication(int& argc, char** argv) : + QApplication(argc, argv) + { + } + + bool SafeApplication::notify(QObject *receiver, QEvent *e) + { + try { + return QApplication::notify(receiver, e); + } catch (const std::exception& e) { + qDebug () << e.what(); + } catch (const CORBA::TRANSIENT& e) { + emit log (QString ("CORBA Exception %1 - %2.\nYou may need to reset the connections (see Tools menu)").arg(e._name()).arg(e._rep_id())); + } catch (const CORBA::COMM_FAILURE& e) { + emit log (QString ("CORBA Exception %1 - %2.\nYou may need to reset the connections (see Tools menu)").arg(e._name()).arg(e._rep_id())); + } catch (const CORBA::Exception& e) { + bool handled = false; + foreach (CorbaInterface* errorHandler, MainWindow::instance()->pluginManager()->get <CorbaInterface>()) { + if (errorHandler->corbaException (0, e)) { + handled = true; + break; + } + } + if (!handled) + emit log (QString ("Unhandled CORBA Exception %1 - %2").arg(e._name()).arg(e._rep_id())); + } catch (...) { + qDebug() << "Unknown exception"; + qDebug() << "Catch it in SafeApplication::notify"; + } + return false; + } + } // namespace gui +} // namespace gepetto diff --git a/src/gui/settings.cc b/src/gui/settings.cc new file mode 100644 index 0000000..5a63557 --- /dev/null +++ b/src/gui/settings.cc @@ -0,0 +1,407 @@ +// Copyright (c) 2015, Joseph Mirabel +// Authors: Joseph Mirabel (joseph.mirabel@laas.fr) +// +// This file is part of hpp-gui. +// hpp-gui is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation, either version +// 3 of the License, or (at your option) any later version. +// +// hpp-gui is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty +// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Lesser Public License for more details. You should have +// received a copy of the GNU Lesser General Public License along with +// hpp-gui. If not, see <http://www.gnu.org/licenses/>. + +#include <gepetto/gui/settings.hh> + +#include <boost/program_options.hpp> +#include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/classification.hpp> + +#include <QSettings> +#include <QDir> +#include <QtDebug> + +#include <gepetto/gui/dialog/dialogloadrobot.hh> +#include <gepetto/gui/dialog/dialogloadenvironment.hh> +#include <gepetto/gui/mainwindow.hh> + +namespace po = boost::program_options; + +namespace gepetto { + namespace gui { + Settings::Settings () + : configurationFile ("settings") + , predifinedRobotConf ("robots") + , predifinedEnvConf ("environments") + , verbose (false) + , noPlugin (false) + , startGepettoCorbaServer (true) + , refreshRate (30) + , captureDirectory ("/tmp/hpp-gui") + , captureFilename ("screenshot") + , captureExtension ("png") + + , mw (0) + {} + + int Settings::fromArgv(const int argc, char * const argv[]) + { + typedef std::vector <std::string> Strings_t; + + bool help = false; + bool genAndQuit = false; + int retVal = 0; + + // Declare the supported options. + po::options_description desc("Options"); + desc.add_options() + ("help,h", "produce help message") + ("verbose,v", "activate verbose output") + ("generate-config-files,g", "generate configuration files and quit") + + ("config-file,c", + po::value<std::string>(&configurationFile), + "set the configuration file (do not include .conf)") + + ("predefined-robots", + po::value<std::string>(&predifinedRobotConf), + "set the predefined robots configuration file (do not include .conf)") + + ("predefined-environments", + po::value<std::string>(&predifinedEnvConf), + "set the predefined environments configuration file (do not include .conf)") + + ("add-robot", po::value <Strings_t>(), + "Add a robot (a list of comma sperated string)") + + ("add-env", po::value <Strings_t>(), + "Add an environment (a list of comma sperated string)") + + ("load-plugin,p", po::value <Strings_t>(), + "load the plugin") + + ("no-plugin,P", "do not load any plugin") + + ("auto-write-settings,w", "write the settings in the configuration file") + + ("no-viewer-server", "do not start the Gepetto Viewer server") + ; + + po::variables_map vm; + po::parsed_options parsed = po::command_line_parser(argc, argv) + .options(desc) + .allow_unregistered() + .run(); + po::store(parsed, vm); + po::notify (vm); + + Strings_t unrecognized = + po::collect_unrecognized (parsed.options, po::exclude_positional); + + help = (vm.count ("help") > 0); + if (vm.count ("verbose") > 0) verbose = true; + if (vm.count ("no-plugin") > 0) noPlugin = true; + if (vm.count ("auto-write-settings") > 0) autoWriteSettings = true; + if (vm.count ("generate-config-files") > 0) genAndQuit = true; + if (vm.count ("no-viewer-server") > 0) startGepettoCorbaServer = false; + if (vm.count ("add-robot") > 0) { + const Strings_t& rbts = vm["add-robot"].as <Strings_t> (); + for (Strings_t::const_iterator it = rbts.begin(); + it != rbts.end(); ++it) + addRobotFromString (*it); + } + if (vm.count ("add-env") > 0) { + const Strings_t& envs = vm["add-env"].as <Strings_t> (); + for (Strings_t::const_iterator it = envs.begin(); + it != envs.end(); ++it) + addEnvFromString (*it); + } + if (vm.count ("load-plugin") > 0) { + const Strings_t& envs = vm["load-plugin"].as <Strings_t> (); + for (Strings_t::const_iterator it = envs.begin(); + it != envs.end(); ++it) + addPlugin (QString::fromStdString(*it), !noPlugin); + } + + if (help || genAndQuit) retVal = 1; + if (unrecognized.size () > 0) { + std::cout << "Unrecognized options:\n"; + for (std::size_t i = 0; i < unrecognized.size (); ++i) + std::cout << unrecognized[i] << "\n"; + std::cout << "\n"; + help = true; + verbose = true; + retVal = 2; + } + + if (help) std::cout << desc << std::endl; + if (verbose) print (std::cout) << std::endl; + if (genAndQuit) writeSettings (); + + return retVal; + } + + void Settings::fromFiles () + { + readRobotFile(); + readEnvFile(); + readSettingFile(); + } + + void Settings::writeSettings() + { + writeRobotFile (); + writeEnvFile (); + writeSettingFile (); + } + + void Settings::initPlugins() + { + foreach (QString name, pluginsToInit_) + pluginManager_.initPlugin (name); + } + + void Settings::setMainWindow(gepetto::gui::MainWindow *main) + { + mw = main; + } + + std::ostream& Settings::print (std::ostream& os) { + const char tab = '\t'; + const char nl = '\n'; + return os + << nl << "Configuration:" + << nl << tab << "Configuration file: " << tab << configurationFile + << nl << tab << "Predefined robots: " << tab << predifinedRobotConf + << nl << tab << "Predefined environments:" << tab << predifinedEnvConf + + << nl << nl << "Options:" + << nl << tab << "Verbose: " << tab << verbose + << nl << tab << "No plugin: " << tab << noPlugin + << nl << tab << "Start Viewer server: " << tab << startGepettoCorbaServer + << nl << tab << "Refresh rate: " << tab << refreshRate + + << nl << nl << "Screen capture options:" + << nl << tab << "Directory: " << tab << captureDirectory + << nl << tab << "Filename: " << tab << captureFilename + << nl << tab << "Extension: " << tab << captureExtension + ; + } + + void Settings::readRobotFile () + { + QSettings robot (QSettings::SystemScope, + QCoreApplication::organizationName(), + QString::fromStdString(predifinedRobotConf)); + if (robot.status() != QSettings::NoError) { + logError(QString ("Enable to open configuration file ") + + robot.fileName()); + } else { + foreach (QString name, robot.childGroups()) { + robot.beginGroup(name); + QString robotName = robot.value("RobotName", name).toString(); + QDir packagePath (robot.value("PackagePath", "").toString()); + QString meshDirectory; + if (packagePath.exists()) { + QDir meshDir = packagePath; meshDir.cdUp(); + meshDirectory = robot.value("MeshDirectory", meshDir.absolutePath()).toString(); + } else { + meshDirectory = robot.value("MeshDirectory", "").toString(); + } + DialogLoadRobot::addRobotDefinition( + name, + robotName, + robot.value("RootJointType", "freeflyer").toString(), + robot.value("ModelName", robotName).toString(), + robot.value("Package", packagePath.dirName()).toString(), + packagePath.path(), + robot.value("URDFSuffix", "").toString(), + robot.value("SRDFSuffix", "").toString(), + meshDirectory + ); + robot.endGroup(); + } + log(QString ("Read configuration file ") + + robot.fileName()); + } + } + + void Settings::readEnvFile () + { + QSettings env (QSettings::SystemScope, + QCoreApplication::organizationName(), + QString::fromStdString(predifinedEnvConf)); + if (env.status() != QSettings::NoError) { + logError(QString ("Enable to open configuration file ") + env.fileName()); + } else { + foreach (QString name, env.childGroups()) { + env.beginGroup(name); + QString envName = env.value("EnvironmentName", name).toString(); + QDir packagePath (env.value("PackagePath", "").toString()); + QString meshDirectory; + if (packagePath.exists()) { + QDir meshDir = packagePath; meshDir.cdUp(); + meshDirectory = env.value("MeshDirectory", meshDir.absolutePath()).toString(); + } else { + meshDirectory = env.value("MeshDirectory", "").toString(); + } + DialogLoadEnvironment::addEnvironmentDefinition( + name, + envName, + env.value("Package", packagePath.dirName()).toString(), + packagePath.path(), + env.value("URDFFilename").toString(), + env.value("URDFSuffix").toString(), + env.value("SRDFSuffix").toString(), + meshDirectory + ); + env.endGroup(); + } + log (QString ("Read configuration file ") + env.fileName()); + } + } + + void Settings::readSettingFile () + { + QSettings env (QSettings::SystemScope, + QCoreApplication::organizationName(), + QString::fromStdString(configurationFile)); + if (env.status() != QSettings::NoError) { + logError(QString ("Enable to open configuration file ") + env.fileName()); + } else { + env.beginGroup("plugins"); + foreach (QString name, env.childKeys()) { + addPlugin (name, (noPlugin)?false:env.value(name, true).toBool()); + } + env.endGroup (); + log (QString ("Read configuration file ") + env.fileName()); + } + } + + void Settings::writeRobotFile () + { + QSettings robot (QSettings::SystemScope, + QCoreApplication::organizationName(), + QString::fromStdString(predifinedRobotConf)); + if (!robot.isWritable()) { + log (QString("Configuration file ") + robot.fileName() + QString(" is not writable.")); + return; + } + foreach (DialogLoadRobot::RobotDefinition rd, DialogLoadRobot::getRobotDefinitions()) { + if (rd.name_.isEmpty()) continue; + robot.beginGroup(rd.name_); + robot.setValue("RobotName", rd.robotName_); + robot.setValue("ModelName", rd.modelName_); + robot.setValue("RootJointType", rd.rootJointType_); + robot.setValue("Package", rd.package_); + robot.setValue("PackagePath", rd.packagePath_); + robot.setValue("URDFSuffix", rd.urdfSuf_); + robot.setValue("SRDFSuffix", rd.srdfSuf_); + robot.setValue("MeshDirectory", rd.mesh_); + robot.endGroup(); + } + log (QString("Wrote configuration file ") + robot.fileName()); + } + + void Settings::writeEnvFile () + { + QSettings env (QSettings::SystemScope, + QCoreApplication::organizationName(), + QString::fromStdString(predifinedEnvConf)); + if (!env.isWritable()) { + logError (QString ("Configuration file") + env.fileName() + QString("is not writable.")); + return; + } + foreach (DialogLoadEnvironment::EnvironmentDefinition ed, DialogLoadEnvironment::getEnvironmentDefinitions()) { + if (ed.name_.isEmpty()) continue; + env.beginGroup(ed.name_); + env.setValue("RobotName", ed.envName_); + env.setValue("Package", ed.package_); + env.setValue("PackagePath", ed.packagePath_); + env.setValue("URDFFilename", ed.urdfFilename_); + env.setValue("MeshDirectory", ed.mesh_); + env.endGroup(); + } + log (QString ("Wrote configuration file ") + env.fileName()); + } + + void Settings::writeSettingFile () + { + QSettings env (QSettings::SystemScope, + QCoreApplication::organizationName(), + QString::fromStdString(configurationFile)); + if (!env.isWritable()) { + logError (QString ("Configuration file") + env.fileName() + QString("is not writable.")); + return; + } + env.beginGroup("plugins"); + for (PluginManager::Map::const_iterator p = pluginManager_.plugins ().constBegin(); + p != pluginManager_.plugins().constEnd(); p++) { + env.setValue(p.key(), (noPlugin)?false:p.value()->isLoaded()); + } + env.endGroup (); + log (QString ("Read configuration file ") + env.fileName()); + } + + QVariant Settings::getSetting (const QString & key, + const QVariant & defaultValue) + { + QSettings env (QSettings::SystemScope, + QCoreApplication::organizationName(), + QString::fromStdString(configurationFile)); + if (env.status() == QSettings::NoError) { + return env.value (key, defaultValue); + } + return defaultValue; + } + + void Settings::addRobotFromString (const std::string& rbtStr) + { + QString rbt = QString::fromStdString(rbtStr); + QStringList split = rbt.split(",", QString::KeepEmptyParts); + if (split.size() != 9) { + logError ("Robot string is not of length 9"); + logError (rbt); + return; + } + DialogLoadRobot::addRobotDefinition(split[0], split[1], + split[2].toLower(), split[3], split[4], + split[5], split[6], split[7], split[8]); + } + + void Settings::addEnvFromString (const std::string& envStr) + { + QString env = QString::fromStdString(envStr); + QStringList split = env.split(",", QString::KeepEmptyParts); + if (split.size() != 6) { + logError ("Environment string is not of length 6"); + logError (env); + return; + } + DialogLoadEnvironment::addEnvironmentDefinition(split[0], + split[1], split[2], split[3], split[4], split[5], split[6], split[7]); + } + + void Settings::addPlugin (const QString& plg, bool init) + { + if (init) pluginsToInit_.append (plg); + pluginManager_.add(plg, 0, false); + } + + void Settings::log(const QString &t) + { + if (!verbose) return; + if (mw) mw->log(t); + else std::cout << t.toLocal8Bit().constData() << std::endl; + } + + void Settings::logError(const QString &t) + { + if (mw) mw->logError(t); + else qWarning() << t; + } + } // namespace gui +} // namespace gepetto diff --git a/src/gui/tree-item.cc b/src/gui/tree-item.cc new file mode 100644 index 0000000..627becc --- /dev/null +++ b/src/gui/tree-item.cc @@ -0,0 +1,143 @@ +#include "gepetto/gui/tree-item.hh" + +#include <QDebug> + +#include <gepetto/viewer/group-node.h> + +#include "gepetto/gui/mainwindow.hh" +#include "gepetto/gui/windows-manager.hh" +#include <gepetto/gui/bodytreewidget.hh> + +namespace gepetto { + namespace gui { + BodyTreeItem::BodyTreeItem(QObject *parent, graphics::NodePtr_t node) : + QObject (parent), + QStandardItem (QString (node->getID().c_str())), + node_ (node), + vmMapper_ (), + vizMapper_ () + { + init(); + setEditable(false); + connect (&vmMapper_, SIGNAL (mapped (QString)), SLOT(setViewingMode(QString))); + connect (&vizMapper_, SIGNAL (mapped (QString)), SLOT(setVisibilityMode(QString))); + } + + QStandardItem* BodyTreeItem::clone() const + { + return new BodyTreeItem (QObject::parent(), node_); + } + + graphics::NodePtr_t BodyTreeItem::node() const + { + return node_; + } + + void BodyTreeItem::populateContextMenu(QMenu *contextMenu) + { + /// Landmark + QMenu* lm = contextMenu->addMenu (tr("Landmark")); + QAction* alm = lm->addAction (tr("Add")); + QAction* dlm = lm->addAction (tr("Remove")); + connect (alm, SIGNAL (triggered()), SLOT (addLandmark())); + connect (dlm, SIGNAL (triggered()), SLOT (deleteLandmark())); + /// Remove + QAction* remove = contextMenu->addAction (tr("Remove")); + connect (remove, SIGNAL (triggered()), SLOT (remove())); + QAction* removeAll = contextMenu->addAction (tr("Remove all")); + connect (removeAll, SIGNAL (triggered()), SLOT (removeAll())); + if (!parentGroup_.empty()) { + QAction* rfg = contextMenu->addAction (tr("Remove from group")); + connect (rfg, SIGNAL (triggered()), SLOT (removeFromGroup ())); + } + /// Viewing mode + QMenu* viewmode = contextMenu->addMenu(tr("Viewing mode")); + QAction* f = viewmode->addAction ("Fill"); + QAction* w = viewmode->addAction ("Wireframe"); + QAction* fw = viewmode->addAction ("Fill and Wireframe"); + vmMapper_.setMapping (f , QString ("FILL")); + vmMapper_.setMapping (w , QString ("WIREFRAME")); + vmMapper_.setMapping (fw, QString ("FILL_AND_WIREFRAME")); + connect (f , SIGNAL(triggered()), &vmMapper_, SLOT (map())); + connect (w , SIGNAL(triggered()), &vmMapper_, SLOT (map())); + connect (fw, SIGNAL(triggered()), &vmMapper_, SLOT (map())); + /// Visibility mode + QMenu* vizmode = contextMenu->addMenu(tr("Visibility mode")); + QAction* on = vizmode->addAction ("On"); + QAction* aot = vizmode->addAction ("Always on top"); + QAction* off = vizmode->addAction ("Off"); + vizMapper_.setMapping (on , QString ("ON")); + vizMapper_.setMapping (aot, QString ("ALWAYS_ON_TOP")); + vizMapper_.setMapping (off, QString ("OFF")); + connect (on , SIGNAL(triggered()), &vizMapper_, SLOT (map())); + connect (aot, SIGNAL(triggered()), &vizMapper_, SLOT (map())); + connect (off, SIGNAL(triggered()), &vizMapper_, SLOT (map())); + } + + void BodyTreeItem::setParentGroup(const std::string &parent) + { + parentGroup_ = parent; + } + + void BodyTreeItem::init () + { + graphics::GroupNodePtr_t gn = boost::dynamic_pointer_cast <graphics::GroupNode> (node_); + if (gn) { + for (size_t i = 0; i < gn->getNumOfChildren(); ++i) { + BodyTreeItem* item = new BodyTreeItem (this, gn->getChild(i)); + item->setParentGroup (gn->getID()); + appendRow(item); + } + } + } + + void BodyTreeItem::setViewingMode(QString mode) + { + MainWindow::instance()->osg()->setWireFrameMode (node_->getID().c_str(), + mode.toLocal8Bit().data()); + } + + void BodyTreeItem::setVisibilityMode(QString mode) + { + MainWindow::instance()->osg()->setVisibility (node_->getID().c_str(), + mode.toLocal8Bit().data()); + } + + void BodyTreeItem::attachToWindow(unsigned int windowID) + { + MainWindow::instance()->osg()->addSceneToWindow (node_->getID().c_str(), windowID); + } + + void BodyTreeItem::removeFromGroup() + { + if (parentGroup_.empty()) return; + MainWindow::instance()->osg()->removeFromGroup (node_->getID().c_str(), + parentGroup_.c_str()); + QStandardItem::parent()->removeRow(row()); + } + + void BodyTreeItem::removeAll() + { + MainWindow* main = MainWindow::instance(); + main->osg()->deleteNode(node_->getID().c_str(), true); + main->bodyTree()->reloadBodyTree(); + } + + void BodyTreeItem::remove() + { + MainWindow* main = MainWindow::instance(); + main->osg()->deleteNode(node_->getID().c_str(), false); + main->bodyTree()->reloadBodyTree(); + } + + void BodyTreeItem::addLandmark() + { + MainWindow::instance()->osg()->addLandmark(node_->getID().c_str(), 0.05f); + } + + void BodyTreeItem::deleteLandmark() + { + MainWindow::instance()->osg()->deleteLandmark(node_->getID().c_str()); + } + } // namespace gui +} // namespace gepetto diff --git a/src/gui/windows-manager.cc b/src/gui/windows-manager.cc new file mode 100644 index 0000000..2ecd0d9 --- /dev/null +++ b/src/gui/windows-manager.cc @@ -0,0 +1,35 @@ +#include "gepetto/gui/windows-manager.hh" + +#include <gepetto/viewer/window-manager.h> + +#include "gepetto/gui/osgwidget.hh" +#include "gepetto/gui/mainwindow.hh" + +namespace gepetto { + namespace gui { + WindowsManagerPtr_t WindowsManager::create() + { + return WindowsManagerPtr_t (new WindowsManager()); + } + + WindowsManager::WindowID WindowsManager::createWindow(const char *windowNameCorba) + { + return MainWindow::instance()->delayedCreateView(QString (windowNameCorba))->windowID(); + } + + WindowsManager::WindowID WindowsManager::createWindow(const char *windowNameCorba, + osgViewer::Viewer *viewer, + osg::GraphicsContext *gc) + { + std::string wn (windowNameCorba); + graphics::WindowManagerPtr_t newWindow = graphics::WindowManager::create (viewer, gc); + WindowID windowId = addWindow (wn, newWindow); + return windowId; + } + + WindowsManager::WindowsManager() + : Parent_t () + { + } + } // namespace gui +} // namespace gepetto -- GitLab