diff --git a/visualization/motion_planning_tasks/src/task_list_model.cpp b/visualization/motion_planning_tasks/src/task_list_model.cpp index 26dcdf83..e04b0b92 100644 --- a/visualization/motion_planning_tasks/src/task_list_model.cpp +++ b/visualization/motion_planning_tasks/src/task_list_model.cpp @@ -2,6 +2,7 @@ * Software License Agreement (BSD License) * * Copyright (c) 2017, Bielefeld University + * Copyright (c) 2020, Hamburg University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -359,99 +360,7 @@ Qt::DropActions TaskListModel::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } -AutoAdjustingTreeView::AutoAdjustingTreeView(QWidget* parent) : QTreeView(parent) { -// consider viewportSizeHint() -#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) - setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents); -#endif -} - -void AutoAdjustingTreeView::setStretchSection(int section) { - stretch_section_ = section; - updateGeometry(); -} - -void AutoAdjustingTreeView::setAutoHideSections(const QList& sections) { - auto_hide_cols_ = sections; - updateGeometry(); -} - -void AutoAdjustingTreeView::setModel(QAbstractItemModel* model) { - size_hints_.clear(); - QTreeView::setModel(model); - - updateGeometry(); -} - -QSize AutoAdjustingTreeView::viewportSizeHint() const { - bool preferred = sizePolicy().horizontalPolicy() & QSizePolicy::ShrinkFlag; - auto m = model(); - auto* h = header(); - size_hints_.clear(); - - int width = 0; - for (int i = 0, end = m ? m->columnCount() : 0; i < end; ++i) { - size_hints_.push_back(h->sectionSizeHint(i)); - if (preferred || !auto_hide_cols_.contains(i)) - width += size_hints_.back(); - } - - QSize main_size(width, sizeHintForRow(0) * ((!preferred || !m) ? 2 : m->rowCount())); - - // add size for header - QSize header_size(0, header()->isVisible() ? header()->height() : 0); - - // add size for scrollbars - QSize scrollbars(verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0, - horizontalScrollBar()->isVisible() ? horizontalScrollBar()->height() : 0); - - return main_size + header_size + scrollbars; -} - -void AutoAdjustingTreeView::resizeEvent(QResizeEvent* event) { - auto* m = model(); - int columns = m ? m->columnCount() : 0; - if ((int)size_hints_.size() != columns) - viewportSizeHint(); - - // auto hide/show columns > 0, stretch last column to width - int available_width = event->size().width(); - - int required_width = std::accumulate(size_hints_.begin(), size_hints_.end(), 0); - std::vector width = size_hints_; - - // if required is larger than available width, try to hide some columns - QListIterator it(auto_hide_cols_); - for (it.toBack(); it.hasPrevious() && required_width > available_width;) { - int section = it.previous(); - required_width -= size_hints_[section]; - width[section] = 0; - } - - // extend width to current column width if possible - for (int i = 0; i < columns; ++i) { - if (i == stretch_section_) - continue; // ignore auto-stretch section for now - int delta = columnWidth(i) > 0 ? columnWidth(i) - width[i] : 0; - if (delta < 0 || required_width + delta <= available_width) { - width[i] += delta; - required_width += delta; - } - } - - // stretch section if there is still space available - if (stretch_section_ >= 0 && stretch_section_ < (int)width.size() && width[stretch_section_] > 0 && - available_width > required_width) - width[stretch_section_] += available_width - required_width; - - // apply stuff - for (int i = 0; i < columns; ++i) - setColumnWidth(i, width[i]); -} - -TaskListView::TaskListView(QWidget* parent) : AutoAdjustingTreeView(parent) { - setStretchSection(0); -} +TaskListView::TaskListView(QWidget* parent) : QTreeView(parent) {} // dropping onto an item, should expand this item void TaskListView::dropEvent(QDropEvent* event) { @@ -460,6 +369,64 @@ void TaskListView::dropEvent(QDropEvent* event) { if (event->isAccepted()) expand(index); } + +void TaskListView::setModel(QAbstractItemModel* model) { + QTreeView::setModel(model); + if (header()->count() >= 4) { + header()->setSectionResizeMode(0, QHeaderView::Stretch); + updateColumnWidth(); + } +} + +void TaskListView::dataChanged(const QModelIndex& /*topLeft*/, const QModelIndex& bottomRight, + const QVector& /*roles*/) { + if (bottomRight.column() > 0) { + updateColumnWidth(); + } +} + +void TaskListView::updateColumnWidth() { + for (int i = 3; i > 0; --i) { + header()->setSectionResizeMode(i, QHeaderView::ResizeToContents); + } +} + +SolutionListView::SolutionListView(QWidget* parent) : QTreeView(parent) {} + +void SolutionListView::setModel(QAbstractItemModel* model) { + QTreeView::setModel(model); + updateColumnWidth(); +} + +void SolutionListView::dataChanged(const QModelIndex& /*topLeft*/, const QModelIndex& bottomRight, + const QVector& /*roles*/) { + if (bottomRight.column() > 0) { + updateColumnWidth(); + } +} + +void SolutionListView::resizeEvent(QResizeEvent* e) { + QTreeView::resizeEvent(e); + updateColumnWidth(); +} + +void SolutionListView::updateColumnWidth() { + // do nothing if current model is not what we expect + if (header()->count() < 3) { + return; + } + + for (int i = 0; i < 2; ++i) { + header()->setSectionResizeMode(i, QHeaderView::ResizeToContents); + } + + const int stretch_size = viewport()->size().width() - header()->sectionPosition(2); + + const int content_size = sizeHintForColumn(2); + + header()->resizeSection(2, std::max(stretch_size, content_size)); +} + } // namespace moveit_rviz_plugin #include "moc_task_list_model.cpp" diff --git a/visualization/motion_planning_tasks/src/task_list_model.h b/visualization/motion_planning_tasks/src/task_list_model.h index 13a31b5b..fd27c159 100644 --- a/visualization/motion_planning_tasks/src/task_list_model.h +++ b/visualization/motion_planning_tasks/src/task_list_model.h @@ -2,6 +2,7 @@ * Software License Agreement (BSD License) * * Copyright (c) 2017, Bielefeld University + * Copyright (c) 2020, Hamburg University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,6 +48,7 @@ #include #include +#include #include #include @@ -178,34 +180,34 @@ protected Q_SLOTS: void highlightStage(size_t id); }; -class AutoAdjustingTreeView : public QTreeView -{ - Q_OBJECT - Q_PROPERTY(int stretchSection READ stretchSection WRITE setStretchSection) - - mutable std::vector size_hints_; // size hints for sections - QList auto_hide_cols_; // auto-hiding sections - int stretch_section_ = -1; - -public: - AutoAdjustingTreeView(QWidget* parent = nullptr); - - int stretchSection() const { return stretch_section_; } - void setStretchSection(int section); - - void setAutoHideSections(const QList& sections); - - void setModel(QAbstractItemModel* model) override; - QSize viewportSizeHint() const override; - void resizeEvent(QResizeEvent* event) override; -}; - -class TaskListView : public AutoAdjustingTreeView +class TaskListView : public QTreeView { Q_OBJECT public: TaskListView(QWidget* parent = nullptr); void dropEvent(QDropEvent* event) override; + + void setModel(QAbstractItemModel* model) override; + void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, + const QVector& roles = QVector()) override; + +protected: + void updateColumnWidth(); +}; + +class SolutionListView : public QTreeView +{ + Q_OBJECT +public: + SolutionListView(QWidget* parent = nullptr); + + void setModel(QAbstractItemModel* model) override; + void dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, + const QVector& roles = QVector()) override; + void resizeEvent(QResizeEvent* event) override; + +protected: + void updateColumnWidth(); }; } // namespace moveit_rviz_plugin diff --git a/visualization/motion_planning_tasks/src/task_panel.cpp b/visualization/motion_planning_tasks/src/task_panel.cpp index 797d69f8..fee4cad9 100644 --- a/visualization/motion_planning_tasks/src/task_panel.cpp +++ b/visualization/motion_planning_tasks/src/task_panel.cpp @@ -234,9 +234,6 @@ TaskViewPrivate::TaskViewPrivate(TaskView* q_ptr) : q_ptr(q_ptr), exec_action_cl tasks_view->setDropIndicatorShown(true); tasks_view->setDragEnabled(true); - solutions_view->setAutoHideSections({ 1, 2 }); - solutions_view->setStretchSection(2); - // init actions tasks_view->addActions({ actionAddLocalTask, actionRemoveTaskTreeRows }); } @@ -304,15 +301,15 @@ void TaskView::save(rviz::Config config) { write_splitter_sizes(d_ptr->tasks_property_splitter, "property_splitter"); write_splitter_sizes(d_ptr->tasks_solutions_splitter, "solutions_splitter"); - auto write_column_sizes = [&config](QTreeView* view, const QString& key) { + auto write_column_sizes = [&config](QHeaderView* view, const QString& key) { rviz::Config group = config.mapMakeChild(key); - for (int c = 0, end = view->header()->count(); c != end; ++c) { + for (int c = 0, end = view->count(); c != end; ++c) { rviz::Config item = group.listAppendNew(); - item.setValue(view->columnWidth(c)); + item.setValue(view->sectionSize(c)); } }; - write_column_sizes(d_ptr->tasks_view, "tasks_view_columns"); - write_column_sizes(d_ptr->solutions_view, "solutions_view_columns"); + write_column_sizes(d_ptr->tasks_view->header(), "tasks_view_columns"); + write_column_sizes(d_ptr->solutions_view->header(), "solutions_view_columns"); const QHeaderView* view = d_ptr->solutions_view->header(); rviz::Config group = config.mapMakeChild("solution_sorting"); @@ -413,10 +410,10 @@ void TaskView::onCurrentStageChanged(const QModelIndex& current, const QModelInd } // update the PropertyModel - view = d_ptr->property_view; - sm = view->selectionModel(); + QTreeView* pview = d_ptr->property_view; + sm = pview->selectionModel(); m = task ? task->getPropertyModel(task_index) : nullptr; - view->setModel(m); + pview->setModel(m); delete sm; // we don't store the selection model } diff --git a/visualization/motion_planning_tasks/src/task_view.ui b/visualization/motion_planning_tasks/src/task_view.ui index 8ae8aa59..bdda7ec6 100644 --- a/visualization/motion_planning_tasks/src/task_view.ui +++ b/visualization/motion_planning_tasks/src/task_view.ui @@ -31,7 +31,7 @@ Qt::Vertical - + 0 @@ -64,11 +64,23 @@ Qt::ActionsContextMenu + + 15 + + + true + + + true + + + true + false - + 1 @@ -78,6 +90,15 @@ QAbstractItemView::ExtendedSelection + + QAbstractItemView::SelectRows + + + Qt::ElideNone + + + QAbstractItemView::ScrollPerPixel + false @@ -87,15 +108,15 @@ true - - false - + + true + - + 0 @@ -141,16 +162,16 @@ QTreeView
task_list_model.h
- - moveit_rviz_plugin::AutoAdjustingTreeView - QTreeView -
task_list_model.h
-
rviz::PropertyTreeWidget QTreeView
rviz/properties/property_tree_widget.h
+ + moveit_rviz_plugin::SolutionListView + QTreeView +
task_list_model.h
+