Implemented non opaque resizing for ResizeHandle

This commit is contained in:
Uwe Kindler 2022-10-26 14:35:11 +02:00
parent 5199fa45d1
commit f22d62a85b
2 changed files with 136 additions and 65 deletions

View File

@ -14,6 +14,8 @@
#include <QStyle>
#include <QStyleOption>
#include <QMouseEvent>
#include <QRubberBand>
#include <QPointer>
#include "ads_globals.h"
@ -31,6 +33,9 @@ struct ResizeHandlePrivate
bool Pressed = false;
int MinSize = 0;
int MaxSize = 1;
QPointer<QRubberBand> 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
//---------------------------------------------------------------------------

View File

@ -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