diff --git a/src/rviz/properties/splitter_handle.cpp b/src/rviz/properties/splitter_handle.cpp index cd513a6127..21f18bcf52 100644 --- a/src/rviz/properties/splitter_handle.cpp +++ b/src/rviz/properties/splitter_handle.cpp @@ -49,9 +49,7 @@ SplitterHandle::SplitterHandle(QTreeView* parent) bool SplitterHandle::eventFilter(QObject* event_target, QEvent* event) { - if (event_target == parent_ && - (event->type() == QEvent::Resize || event->type() == QEvent::LayoutRequest || - event->type() == QEvent::Show)) + if (event_target == parent_ && event->type() == QEvent::Resize) { updateGeometry(); } @@ -61,13 +59,14 @@ bool SplitterHandle::eventFilter(QObject* event_target, QEvent* event) void SplitterHandle::updateGeometry() { int w = 7; - int new_column_width = int(first_column_size_ratio_ * parent_->contentsRect().width()); - parent_->setColumnWidth(0, new_column_width); - parent_->setColumnWidth(1, parent_->viewport()->contentsRect().width() - new_column_width); - - int new_x = new_column_width - w / 2 + parent_->columnViewportPosition(0); - if (new_x != x() || parent_->height() != height()) - setGeometry(new_x, 0, w, parent_->height()); + const auto& content = parent_->contentsRect(); + int new_column_width = int(first_column_size_ratio_ * content.width()); + parent_->header()->resizeSection(0, new_column_width); // fixed size for name column + parent_->header()->resizeSection(1, content.width() - new_column_width); + + int new_x = content.x() + new_column_width - w / 2; + if (new_x != x() || content.height() != height()) + setGeometry(new_x, content.y(), w, content.height()); } void SplitterHandle::setRatio(float ratio) @@ -81,49 +80,60 @@ float SplitterHandle::getRatio() return first_column_size_ratio_; } +void SplitterHandle::setDesiredWidth(int width) +{ + const auto& content = parent_->contentsRect(); + int new_column_width = qBound(parent_->header()->minimumSectionSize(), // minimum + width, // desired + content.width()); // maximum + + if (new_column_width != parent_->header()->sectionSize(0)) + { + first_column_size_ratio_ = new_column_width / (float)content.width(); + updateGeometry(); + } +} + void SplitterHandle::mousePressEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) { - // position of mouse press inside this QWidget - x_press_offset_ = event->x(); + // position of mouse press relative to splitter line / the center of the widget + x_press_offset_ = event->x() - width() / 2; } } void SplitterHandle::mouseMoveEvent(QMouseEvent* event) { - int padding = 55; - if (event->buttons() & Qt::LeftButton) { QPoint pos_rel_parent = parent_->mapFromGlobal(event->globalPos()); - - int new_x = pos_rel_parent.x() - x_press_offset_ - parent_->columnViewportPosition(0); - - if (new_x > parent_->width() - width() - padding) - { - new_x = parent_->width() - width() - padding; - } - - if (new_x < padding) - { - new_x = padding; - } - - if (new_x != x()) - { - int new_column_width = new_x + width() / 2 - parent_->contentsRect().x(); - first_column_size_ratio_ = new_column_width / (float)parent_->contentsRect().width(); - updateGeometry(); - } + setDesiredWidth(pos_rel_parent.x() - parent_->contentsRect().x() - x_press_offset_); } } +// adjust splitter position to optimally fit content +void SplitterHandle::mouseDoubleClickEvent(QMouseEvent* /*event*/) +{ + int available_width = parent_->contentsRect().width(); + int default_width = 0.5f * available_width; + // missing width to default + int col0 = static_cast(parent_)->sizeHintForColumn(0) - default_width; + int col1 = static_cast(parent_)->sizeHintForColumn(1) - default_width; + + if (col0 <= 0 && col1 <= 0) // each column fits + setDesiredWidth(default_width); + else if (col0 + col1 <= 0) // both columns fit together, but require a non-default splitting + setDesiredWidth(default_width + col0 + 0.5f * std::abs(col0 + col1)); // uniformly split extra space + else + setDesiredWidth(default_width + col0 - 0.5f * (col0 + col1)); // uniformly cut missing space +} + void SplitterHandle::paintEvent(QPaintEvent* /*event*/) { QPainter painter(this); painter.setPen(color_); - painter.drawLine(1 + width() / 2, 0, 1 + width() / 2, height()); + painter.drawLine(width() / 2, 0, width() / 2, height()); } } // end namespace rviz diff --git a/src/rviz/properties/splitter_handle.h b/src/rviz/properties/splitter_handle.h index 641ea8c84f..795c94d479 100644 --- a/src/rviz/properties/splitter_handle.h +++ b/src/rviz/properties/splitter_handle.h @@ -51,6 +51,9 @@ class SplitterHandle : public QWidget /** @brief Get the ratio of the parent's left column to the parent widget width. */ float getRatio(); + /** @brief Set desired width of first column - subject to clamping */ + void setDesiredWidth(int width); + /** @brief Catch resize events sent to parent to update splitter's * geometry. Always returns false. */ bool eventFilter(QObject* event_target, QEvent* event) override; @@ -68,6 +71,7 @@ class SplitterHandle : public QWidget protected: void mousePressEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override; + void mouseDoubleClickEvent(QMouseEvent* event) override; void paintEvent(QPaintEvent* event) override; private: