Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Improve SplitterHandle of PropertyTreeWidgets #1760

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 44 additions & 34 deletions src/rviz/properties/splitter_handle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand All @@ -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)
Expand All @@ -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<QAbstractItemView*>(parent_)->sizeHintForColumn(0) - default_width;
int col1 = static_cast<QAbstractItemView*>(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
4 changes: 4 additions & 0 deletions src/rviz/properties/splitter_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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:
Expand Down