mirror of
https://github.com/moveit/moveit_task_constructor.git
synced 2025-11-04 14:49:57 +08:00
extensible TaskPanel
Provide TaskPanel::addSubPanel() to add new sub panels. Each panel can be activated with an associated QToolButton. Sub panels, derived from base class SubPanel, automatically load/save their config settings. All settings are shown in GlobalSettingsWidget (renamed from TaskSettings).
This commit is contained in:
parent
6950cf2b8e
commit
1ce66c758b
@ -3,7 +3,7 @@ set(MOVEIT_LIB_NAME motion_planning_tasks_rviz_plugin)
|
||||
qt_wrap_ui(UIC_FILES
|
||||
task_panel.ui
|
||||
task_view.ui
|
||||
task_settings.ui
|
||||
global_settings.ui
|
||||
)
|
||||
|
||||
add_library(${MOVEIT_LIB_NAME}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>moveit_rviz_plugin::TaskSettings</class>
|
||||
<widget class="QWidget" name="moveit_rviz_plugin::TaskSettings">
|
||||
<class>moveit_rviz_plugin::GlobalSettingsWidget</class>
|
||||
<widget class="QWidget" name="moveit_rviz_plugin::GlobalSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
@ -27,7 +27,7 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="tab_settings_layout">
|
||||
<layout class="QVBoxLayout" name="layout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@ -44,14 +44,14 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="settings_view_label">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Settings</string>
|
||||
<string>Global Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="rviz::PropertyTreeWidget" name="settings_view"/>
|
||||
<widget class="rviz::PropertyTreeWidget" name="view"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
@ -87,15 +87,20 @@ TaskPanel::TaskPanel(QWidget* parent)
|
||||
{
|
||||
Q_D(TaskPanel);
|
||||
|
||||
d->tasks_widget = new TaskView(this);
|
||||
d->settings_widget = new TaskSettings(this);
|
||||
layout()->addWidget(d->tasks_widget);
|
||||
layout()->addWidget(d->settings_widget);
|
||||
connect(d->tasks_widget, SIGNAL(configChanged()), this, SIGNAL(configChanged()));
|
||||
// sync checked tool button with displayed widget
|
||||
connect(d->tool_buttons_group, static_cast<void(QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked),
|
||||
d->stackedWidget, [d](int index) { d->stackedWidget->setCurrentIndex(index); });
|
||||
connect(d->stackedWidget, &QStackedWidget::currentChanged, d->tool_buttons_group,
|
||||
[d](int index) { d->tool_buttons_group->button(index)->setChecked(true); });
|
||||
|
||||
// create sub widgets with corresponding tool buttons
|
||||
addSubPanel(new TaskView(this, d->property_root), "Tasks View", QIcon(":/icons/tasks.png"));
|
||||
d->stackedWidget->setCurrentIndex(0); // Tasks View is show by default
|
||||
|
||||
// settings widget should come last
|
||||
addSubPanel(new GlobalSettingsWidget(this, d->property_root), "Global Settings", QIcon(":/icons/settings.png"));
|
||||
|
||||
connect(d->button_show_stage_dock_widget, SIGNAL(clicked()), this, SLOT(showStageDockWidget()));
|
||||
connect(d->button_show_settings, SIGNAL(toggled(bool)), d->settings_widget, SLOT(setVisible(bool)));
|
||||
d->settings_widget->setVisible(d->button_show_settings->isChecked());
|
||||
|
||||
// if still undefined, this becomes the global instance
|
||||
if (singleton_.isNull())
|
||||
@ -107,6 +112,24 @@ TaskPanel::~TaskPanel()
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void TaskPanel::addSubPanel(SubPanel *w, const QString& title, const QIcon& icon)
|
||||
{
|
||||
Q_D(TaskPanel);
|
||||
|
||||
auto button = new QToolButton(w);
|
||||
button->setToolTip(title);
|
||||
button->setIcon(icon);
|
||||
button->setCheckable(true);
|
||||
|
||||
int index = d->stackedWidget->count();
|
||||
d->tool_buttons_layout->insertWidget(index, button);
|
||||
d->tool_buttons_group->addButton(button, index);
|
||||
d->stackedWidget->addWidget(w);
|
||||
|
||||
w->setWindowTitle(title);
|
||||
connect(w, SIGNAL(configChanged()), this, SIGNAL(configChanged()));
|
||||
}
|
||||
|
||||
void TaskPanel::incDisplayCount(rviz::WindowManagerInterface* window_manager)
|
||||
{
|
||||
++display_count_;
|
||||
@ -132,7 +155,11 @@ TaskPanelPrivate::TaskPanelPrivate(TaskPanel *q_ptr)
|
||||
: q_ptr(q_ptr)
|
||||
{
|
||||
setupUi(q_ptr);
|
||||
tool_buttons_group = new QButtonGroup(q_ptr);
|
||||
tool_buttons_group->setExclusive(true);
|
||||
button_show_stage_dock_widget->setEnabled(bool(getStageFactory()));
|
||||
button_show_stage_dock_widget->setToolTip(QStringLiteral("Show available stages"));
|
||||
property_root = new rviz::Property("Global Settings");
|
||||
}
|
||||
|
||||
void TaskPanel::onInitialize()
|
||||
@ -143,13 +170,19 @@ void TaskPanel::onInitialize()
|
||||
void TaskPanel::save(rviz::Config config) const
|
||||
{
|
||||
rviz::Panel::save(config);
|
||||
d_ptr->tasks_widget->save(config.mapMakeChild("tasks_view"));
|
||||
for (int i=0; i < d_ptr->stackedWidget->count(); ++i) {
|
||||
SubPanel* w = static_cast<SubPanel*>(d_ptr->stackedWidget->widget(i));
|
||||
w->save(config.mapMakeChild(w->windowTitle()));
|
||||
}
|
||||
}
|
||||
|
||||
void TaskPanel::load(const rviz::Config& config)
|
||||
{
|
||||
rviz::Panel::load(config);
|
||||
d_ptr->tasks_widget->load(config.mapGetChild("tasks_view"));
|
||||
for (int i=0; i < d_ptr->stackedWidget->count(); ++i) {
|
||||
SubPanel* w = static_cast<SubPanel*>(d_ptr->stackedWidget->widget(i));
|
||||
w->load(config.mapGetChild(w->windowTitle()));
|
||||
}
|
||||
}
|
||||
|
||||
void TaskPanel::showStageDockWidget()
|
||||
@ -235,8 +268,8 @@ void TaskViewPrivate::lock(TaskDisplay* display)
|
||||
locked_display_ = display;
|
||||
}
|
||||
|
||||
TaskView::TaskView(QWidget *parent)
|
||||
: QWidget(parent), d_ptr(new TaskViewPrivate(this))
|
||||
TaskView::TaskView(moveit_rviz_plugin::TaskPanel *parent, rviz::Property *root)
|
||||
: SubPanel(parent), d_ptr(new TaskViewPrivate(this))
|
||||
{
|
||||
Q_D(TaskView);
|
||||
|
||||
@ -426,23 +459,37 @@ void TaskView::onSolutionSelectionChanged(const QItemSelection &selected, const
|
||||
}
|
||||
|
||||
|
||||
TaskSettingsPrivate::TaskSettingsPrivate(TaskSettings *q_ptr)
|
||||
GlobalSettingsWidgetPrivate::GlobalSettingsWidgetPrivate(GlobalSettingsWidget *q_ptr, rviz::Property *root)
|
||||
: q_ptr(q_ptr)
|
||||
{
|
||||
setupUi(q_ptr);
|
||||
properties = new rviz::PropertyTreeModel(root, q_ptr);
|
||||
view->setModel(properties);
|
||||
}
|
||||
|
||||
TaskSettings::TaskSettings(QWidget *parent)
|
||||
: QWidget(parent), d_ptr(new TaskSettingsPrivate(this))
|
||||
GlobalSettingsWidget::GlobalSettingsWidget(moveit_rviz_plugin::TaskPanel *parent, rviz::Property *root)
|
||||
: SubPanel(parent), d_ptr(new GlobalSettingsWidgetPrivate(this, root))
|
||||
{
|
||||
Q_D(TaskSettings);
|
||||
Q_D(GlobalSettingsWidget);
|
||||
connect(d->properties, &rviz::PropertyTreeModel::configChanged,
|
||||
this, &GlobalSettingsWidget::configChanged);
|
||||
}
|
||||
|
||||
TaskSettings::~TaskSettings()
|
||||
GlobalSettingsWidget::~GlobalSettingsWidget()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void GlobalSettingsWidget::save(rviz::Config config)
|
||||
{
|
||||
d_ptr->properties->getRoot()->save(config);
|
||||
}
|
||||
|
||||
void GlobalSettingsWidget::load(const rviz::Config &config)
|
||||
{
|
||||
d_ptr->properties->getRoot()->load(config);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "moc_task_panel.cpp"
|
||||
|
||||
@ -42,9 +42,11 @@
|
||||
#include <moveit/macros/class_forward.h>
|
||||
#include <QModelIndex>
|
||||
class QItemSelection;
|
||||
class QIcon;
|
||||
|
||||
namespace rviz {
|
||||
class WindowManagerInterface;
|
||||
class Property;
|
||||
}
|
||||
|
||||
namespace moveit_rviz_plugin {
|
||||
@ -53,12 +55,22 @@ class TaskSolutionVisualization;
|
||||
MOVEIT_CLASS_FORWARD(TaskListModel)
|
||||
MOVEIT_CLASS_FORWARD(TaskPanel)
|
||||
|
||||
/** The TaskPanel displays information about manipulation tasks in the system.
|
||||
*
|
||||
* Subscribing to task_monitoring and task_solution topics, it collects information
|
||||
* about running tasks and their solutions and allows to inspect both,
|
||||
* successful solutions and failed solution attempts.
|
||||
*/
|
||||
|
||||
/// Base class for all sub panels within the Task Panel
|
||||
class SubPanel : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
SubPanel(QWidget* parent = nullptr) : QWidget(parent) {}
|
||||
|
||||
virtual void save(rviz::Config config) {}
|
||||
virtual void load(const rviz::Config& config) {}
|
||||
|
||||
Q_SIGNALS:
|
||||
void configChanged();
|
||||
};
|
||||
|
||||
|
||||
/** The TaskPanel is the central panel of this plugin, collecting various sub panels. */
|
||||
class TaskPanelPrivate;
|
||||
class TaskPanel: public rviz::Panel
|
||||
{
|
||||
@ -70,6 +82,9 @@ public:
|
||||
TaskPanel(QWidget* parent = 0);
|
||||
~TaskPanel();
|
||||
|
||||
/// add a new sub panel widget
|
||||
void addSubPanel(SubPanel* w, const QString &title, const QIcon &icon);
|
||||
|
||||
/** Increment/decrement use count of singleton TaskPanel instance.
|
||||
*
|
||||
* If not yet done, an instance is created. If use count drops to zero,
|
||||
@ -88,21 +103,24 @@ protected Q_SLOTS:
|
||||
|
||||
|
||||
class MetaTaskListModel;
|
||||
/** TaskView displays all known tasks.
|
||||
*
|
||||
* Subscribing to task_monitoring and task_solution topics, it collects information
|
||||
* about running tasks and their solutions and allows to inspect both,
|
||||
* successful solutions and failed solution attempts.
|
||||
*/
|
||||
class TaskViewPrivate;
|
||||
class TaskView : public QWidget {
|
||||
class TaskView : public SubPanel {
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(TaskView)
|
||||
TaskViewPrivate *d_ptr;
|
||||
|
||||
public:
|
||||
TaskView(QWidget* parent = 0);
|
||||
TaskView(TaskPanel* parent, rviz::Property* root);
|
||||
~TaskView();
|
||||
|
||||
void save(rviz::Config config);
|
||||
void load(const rviz::Config& config);
|
||||
|
||||
Q_SIGNALS:
|
||||
void configChanged();
|
||||
void save(rviz::Config config) override;
|
||||
void load(const rviz::Config& config) override;
|
||||
|
||||
public Q_SLOTS:
|
||||
void addTask();
|
||||
@ -115,15 +133,18 @@ protected Q_SLOTS:
|
||||
};
|
||||
|
||||
|
||||
class TaskSettingsPrivate;
|
||||
class TaskSettings : public QWidget {
|
||||
class GlobalSettingsWidgetPrivate;
|
||||
class GlobalSettingsWidget : public SubPanel {
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(TaskSettings)
|
||||
TaskSettingsPrivate *d_ptr;
|
||||
Q_DECLARE_PRIVATE(GlobalSettingsWidget)
|
||||
GlobalSettingsWidgetPrivate *d_ptr;
|
||||
|
||||
public:
|
||||
TaskSettings(QWidget* parent = 0);
|
||||
~TaskSettings();
|
||||
GlobalSettingsWidget(TaskPanel* parent, rviz::Property* root);
|
||||
~GlobalSettingsWidget();
|
||||
|
||||
void save(rviz::Config config) override;
|
||||
void load(const rviz::Config &config) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -27,23 +27,9 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<layout class="QHBoxLayout" name="tool_buttons_layout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="button_show_settings">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
<normaloff>:/icons/settings.png</normaloff>:/icons/settings.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<spacer name="spacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@ -68,6 +54,9 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
#include "task_panel.h"
|
||||
#include "ui_task_panel.h"
|
||||
#include "ui_task_view.h"
|
||||
#include "ui_task_settings.h"
|
||||
#include "ui_global_settings.h"
|
||||
|
||||
#include <rviz/panel.h>
|
||||
#include <rviz/properties/property_tree_model.h>
|
||||
@ -58,8 +58,8 @@ public:
|
||||
TaskPanelPrivate(TaskPanel *q_ptr);
|
||||
|
||||
TaskPanel* q_ptr;
|
||||
TaskView* tasks_widget;
|
||||
TaskSettings* settings_widget;
|
||||
QButtonGroup* tool_buttons_group;
|
||||
rviz::Property* property_root;
|
||||
|
||||
rviz::WindowManagerInterface* window_manager_;
|
||||
};
|
||||
@ -85,11 +85,12 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class TaskSettingsPrivate : public Ui_TaskSettings {
|
||||
class GlobalSettingsWidgetPrivate : public Ui_GlobalSettingsWidget {
|
||||
public:
|
||||
TaskSettingsPrivate(TaskSettings *q_ptr);
|
||||
GlobalSettingsWidgetPrivate(GlobalSettingsWidget *q_ptr, rviz::Property *root);
|
||||
|
||||
TaskSettings *q_ptr;
|
||||
GlobalSettingsWidget *q_ptr;
|
||||
rviz::PropertyTreeModel *properties;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user