From f22d62a85b584d1ff500f19e7ffe876a3cc571a9 Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Wed, 26 Oct 2022 14:35:11 +0200 Subject: [PATCH] Implemented non opaque resizing for ResizeHandle --- src/ResizeHandle.cpp | 189 ++++++++++++++++++++++++++++--------------- src/ResizeHandle.h | 12 +++ 2 files changed, 136 insertions(+), 65 deletions(-) diff --git a/src/ResizeHandle.cpp b/src/ResizeHandle.cpp index fd4874f..a29e60c 100644 --- a/src/ResizeHandle.cpp +++ b/src/ResizeHandle.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include "ads_globals.h" @@ -31,6 +33,9 @@ struct ResizeHandlePrivate bool Pressed = false; int MinSize = 0; int MaxSize = 1; + QPointer RubberBand; + bool OpaqueResize = false; + int HandleWidth = 4; /** * Private data constructor @@ -52,6 +57,16 @@ struct ResizeHandlePrivate { return _this->orientation() == Qt::Horizontal; } + + /** + * Set rubberband position + */ + void setRubberBand(int Pos); + + /** + * Calculates the resize position and geometry + */ + void doResizing(QMouseEvent* e, bool ForceResize = false); }; // struct ResizeHandlePrivate @@ -62,6 +77,90 @@ ResizeHandlePrivate::ResizeHandlePrivate(CResizeHandle *_public) : } + +//============================================================================ +void ResizeHandlePrivate::setRubberBand(int Pos) +{ + if (!RubberBand) + { + RubberBand = new QRubberBand(QRubberBand::Line, Target->parentWidget()); + } + + auto Geometry = _this->geometry(); + auto TopLeft = Target->mapTo(Target->parentWidget(), Geometry.topLeft()); + switch (HandlePosition) + { + case Qt::LeftEdge: + case Qt::RightEdge: TopLeft.rx() += Pos; break; + case Qt::TopEdge: + case Qt::BottomEdge: TopLeft.ry() += Pos; break; + } + + Geometry.moveTopLeft(TopLeft); + RubberBand->setGeometry(Geometry); + RubberBand->show(); +} + + +//============================================================================ +void ResizeHandlePrivate::doResizing(QMouseEvent* e, bool ForceResize) +{ + int pos = pick(e->pos()) - MouseOffset; + auto OldGeometry = Target->geometry(); + auto NewGeometry = OldGeometry; + switch (HandlePosition) + { + case Qt::LeftEdge: + { + NewGeometry.adjust(pos, 0, 0, 0); + int Size = qBound(MinSize, NewGeometry.width(), MaxSize); + pos += (NewGeometry.width() - Size); + NewGeometry.setWidth(Size); + NewGeometry.moveTopRight(OldGeometry.topRight()); + } + break; + + + case Qt::RightEdge: + { + NewGeometry.adjust(0, 0, pos, 0); + int Size = qBound(MinSize, NewGeometry.width(), MaxSize); + pos -= (NewGeometry.width() - Size); + NewGeometry.setWidth(Size); + } + break; + + case Qt::TopEdge: + { + NewGeometry.adjust(0, pos, 0, 0); + int Size = qBound(MinSize, NewGeometry.height(), MaxSize); + pos += (NewGeometry.height() - Size); + NewGeometry.setHeight(Size); + NewGeometry.moveBottomLeft(OldGeometry.bottomLeft()); + } + break; + + case Qt::BottomEdge: + { + NewGeometry.adjust(0, 0, 0, pos); + int Size = qBound(MinSize, NewGeometry.height(), MaxSize); + pos -= (NewGeometry.height() - Size); + NewGeometry.setHeight(Size); + } + break; + } + + if (_this->opaqueResize() || ForceResize) + { + Target->setGeometry(NewGeometry); + } + else + { + setRubberBand(pos); + } +} + + //============================================================================ CResizeHandle::CResizeHandle(Qt::Edge HandlePosition, QWidget* parent) : Super(parent), @@ -97,66 +196,14 @@ void CResizeHandle::mouseMoveEvent(QMouseEvent* e) { return; } - int pos = d->pick(e->pos()) - d->MouseOffset; - auto OldGeometry = d->Target->geometry(); - auto NewGeometry = OldGeometry; - switch (d->HandlePosition) - { - case Qt::LeftEdge: - { - NewGeometry.adjust(pos, 0, 0, 0); - int Size = qBound(d->MinSize, NewGeometry.width(), d->MaxSize); - NewGeometry.setWidth(Size); - NewGeometry.moveTopRight(OldGeometry.topRight()); - } - break; - - case Qt::RightEdge: - { - NewGeometry.adjust(0, 0, pos, 0); - int Size = qBound(d->MinSize, NewGeometry.width(), d->MaxSize); - NewGeometry.setWidth(Size); - } - break; - - case Qt::TopEdge: - { - NewGeometry.adjust(0, pos, 0, 0); - int Size = qBound(d->MinSize, NewGeometry.height(), d->MaxSize); - NewGeometry.setHeight(Size); - NewGeometry.moveBottomLeft(OldGeometry.bottomLeft()); - } - break; - - case Qt::BottomEdge: - { - NewGeometry.adjust(0, 0, 0, pos); - int Size = qBound(d->MinSize, NewGeometry.height(), d->MaxSize); - NewGeometry.setHeight(Size); - } - break; - } - d->Target->setGeometry(NewGeometry); - //qDebug() << "globalGeometry(): " << internal::globalGeometry(d->Target); - //qDebug() << "parentGlobalGeometry(): " << internal::globalGeometry(d->Target->parentWidget()); - - - /*if (opaqueResize()) - { - moveSplitter(pos); - } - else - { - //d->s->setRubberBand(closestLegalPosition(pos)); - }*/ + d->doResizing(e); } //============================================================================ void CResizeHandle::mousePressEvent(QMouseEvent* e) { - qDebug() << "CResizeHandle::mousePressEvent " << e; if (e->button() == Qt::LeftButton) { d->MouseOffset = d->pick(e->pos()); @@ -169,13 +216,14 @@ void CResizeHandle::mousePressEvent(QMouseEvent* e) //============================================================================ void CResizeHandle::mouseReleaseEvent(QMouseEvent* e) { - qDebug() << "CResizeHandle::mouseReleaseEvent " << e; - /*if (!opaqueResize() && e->button() == Qt::LeftButton) { - int pos = d->pick(parentWidget()->mapFromGlobal(e->globalPos())) - - d->mouseOffset; - d->s->setRubberBand(-1); - moveSplitter(pos); - }*/ + if (!opaqueResize() && e->button() == Qt::LeftButton) + { + if (d->RubberBand) + { + d->RubberBand->deleteLater(); + } + d->doResizing(e, true); + } if (e->button() == Qt::LeftButton) { d->Pressed = false; @@ -229,16 +277,13 @@ QSize CResizeHandle::sizeHint() const switch (d->HandlePosition) { case Qt::LeftEdge: // fall through - case Qt::RightEdge: Result = QSize(4, d->Target->height()); break; + case Qt::RightEdge: Result = QSize(d->HandleWidth, d->Target->height()); break; case Qt::TopEdge: // fall through - case Qt::BottomEdge: Result = QSize(d->Target->width(), 4); break; + case Qt::BottomEdge: Result = QSize(d->Target->width(), d->HandleWidth); break; } - qDebug() << "CResizeHandle::sizeHint(): " << Result; return Result; - /*parentWidget()->style()->sizeFromContents(QStyle::CT_Splitter, &opt, QSize(hw, hw), d->s) - .expandedTo(QApplication::globalStrut());*/ } @@ -263,6 +308,20 @@ void CResizeHandle::setMaxResizeSize(int MaxSize) qDebug() << "CResizeHandle::setMaxResizeSize " << MaxSize; d->MaxSize = MaxSize; } + + +//============================================================================ +void CResizeHandle::setOpaqueResize(bool opaque) +{ + d->OpaqueResize = opaque; +} + + +//============================================================================ +bool CResizeHandle::opaqueResize() const +{ + return d->OpaqueResize; +} } // namespace ads //--------------------------------------------------------------------------- diff --git a/src/ResizeHandle.h b/src/ResizeHandle.h index 7031306..3907824 100644 --- a/src/ResizeHandle.h +++ b/src/ResizeHandle.h @@ -24,6 +24,7 @@ class ADS_EXPORT CResizeHandle : public QFrame { Q_OBJECT Q_DISABLE_COPY(CResizeHandle) + Q_PROPERTY(bool opaqueResize READ opaqueResize WRITE setOpaqueResize) private: ResizeHandlePrivate* d; ///< private data (pimpl) friend struct ResizeHandlePrivate; @@ -84,6 +85,17 @@ public: * than this value */ void setMaxResizeSize(int MaxSize); + + /** + * Enable / disable opaque resizing + */ + void setOpaqueResize(bool opaque = true); + + /** + * Returns true if widgets are resized dynamically (opaquely) while + * interactively moving the resize handle. Otherwise returns false. + */ + bool opaqueResize() const; }; // class name } // namespace ads