mirror of
https://gitee.com/drabel/LibQQt.git
synced 2025-01-04 10:18:44 +08:00
4327030a8f
use bodymover, use bodyresizer,
344 lines
8.3 KiB
C++
344 lines
8.3 KiB
C++
#include "qqtframelesshelperprivate.h"
|
|
#include <QTimer>
|
|
#include <QWidget>
|
|
#include <QMouseEvent>
|
|
#include <QPushButton>
|
|
#include <QDebug>
|
|
#include <QApplication>
|
|
|
|
QQtFramelessHelperPrivate::QQtFramelessHelperPrivate ( QWidget* parent )
|
|
: parent ( parent ),
|
|
isMaximized ( false ),
|
|
direction ( None ),
|
|
buttonMaximized ( 0 ),
|
|
buttonRestore ( 0 ),
|
|
buttonClose ( 0 ),
|
|
buttonMinimized ( 0 ),
|
|
isMousePressed ( false ),
|
|
QObject ( parent )
|
|
{
|
|
margins = QMargins ( 5, 5, 5, 5 );
|
|
parent->setWindowFlags ( parent->windowFlags() | ( Qt::FramelessWindowHint ) );
|
|
parent->installEventFilter ( this );
|
|
|
|
|
|
timer = new QTimer ( this );
|
|
timer->setInterval ( 200 );
|
|
connect ( timer, SIGNAL ( timeout() ), this, SLOT ( checkPos() ) );
|
|
|
|
timer->start();
|
|
}
|
|
|
|
void QQtFramelessHelperPrivate::addEdgeWidget ( QWidget* widget )
|
|
{
|
|
if ( !edgeWidgets.contains ( widget ) )
|
|
{
|
|
edgeWidgets.append ( widget );
|
|
|
|
if ( !dragWidgets.contains ( widget ) )
|
|
{
|
|
widget->installEventFilter ( this );
|
|
}
|
|
}
|
|
}
|
|
|
|
void QQtFramelessHelperPrivate::addDragWidget ( QWidget* widget )
|
|
{
|
|
if ( !dragWidgets.contains ( widget ) )
|
|
{
|
|
dragWidgets.append ( widget );
|
|
|
|
if ( !edgeWidgets.contains ( widget ) )
|
|
{
|
|
widget->installEventFilter ( this );
|
|
}
|
|
}
|
|
}
|
|
|
|
void QQtFramelessHelperPrivate::checkPos()
|
|
{
|
|
QRect rectMustIn = parent->frameGeometry();
|
|
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
|
QRect rectMustNotIn = rectMustIn.marginsRemoved ( margins );
|
|
#else
|
|
QRect rectMustNotIn = rectMustIn.adjusted ( margins.left(), margins.top(), margins.right(), margins.bottom() );
|
|
#endif
|
|
QPoint cursorPos = QCursor::pos();
|
|
|
|
if ( isMaximized ||
|
|
!parent->isActiveWindow() ||
|
|
!rectMustIn.contains ( cursorPos ) ||
|
|
rectMustNotIn.contains ( cursorPos ) )
|
|
{
|
|
direction = None;
|
|
parent->unsetCursor();
|
|
return;
|
|
}
|
|
|
|
int baseLeftCoord, baseTopCoord, baseRightCoord, baseBottomCoord;
|
|
|
|
rectMustNotIn.getCoords ( &baseLeftCoord, &baseTopCoord, &baseRightCoord, &baseBottomCoord );
|
|
|
|
int x, y;
|
|
x = cursorPos.x();
|
|
y = cursorPos.y();
|
|
|
|
direction = None;
|
|
|
|
if ( x < baseLeftCoord )
|
|
{
|
|
if ( y < baseTopCoord )
|
|
{
|
|
direction = LeftTop;
|
|
}
|
|
else if ( y > baseBottomCoord )
|
|
{
|
|
direction = LeftBottom;
|
|
}
|
|
else
|
|
{
|
|
direction = Left;
|
|
}
|
|
}
|
|
else if ( x > baseRightCoord )
|
|
{
|
|
if ( y < baseTopCoord )
|
|
{
|
|
direction = RightTop;
|
|
}
|
|
else if ( y > baseBottomCoord )
|
|
{
|
|
direction = RightBottom;
|
|
}
|
|
else
|
|
{
|
|
direction = Right;
|
|
}
|
|
}
|
|
|
|
if ( direction == None )
|
|
{
|
|
if ( y < baseTopCoord )
|
|
{
|
|
direction = Top;
|
|
}
|
|
else
|
|
{
|
|
direction = Bottom;
|
|
}
|
|
}
|
|
|
|
switch ( direction )
|
|
{
|
|
case Left:
|
|
case Right:
|
|
parent->setCursor ( Qt::SizeHorCursor );
|
|
break;
|
|
|
|
case Top:
|
|
case Bottom:
|
|
parent->setCursor ( Qt::SizeVerCursor );
|
|
break;
|
|
|
|
case LeftTop:
|
|
case RightBottom:
|
|
parent->setCursor ( Qt::SizeFDiagCursor );
|
|
break;
|
|
|
|
case LeftBottom:
|
|
case RightTop:
|
|
parent->setCursor ( Qt::SizeBDiagCursor );
|
|
break;
|
|
}
|
|
}
|
|
|
|
void QQtFramelessHelperPrivate::resize ( const QPoint& cursorPos )
|
|
{
|
|
QSize oldSize = parent->size();
|
|
|
|
int x, y, width = 0, height = 0;
|
|
|
|
switch ( direction )
|
|
{
|
|
case Left: // left
|
|
width = oldSize.width() - cursorPos.x();
|
|
height = oldSize.height();
|
|
|
|
x = parent->pos().x() - ( width - oldSize.width() );
|
|
y = parent->pos().y();
|
|
break;
|
|
|
|
case Right: //right
|
|
width = cursorPos.x();
|
|
height = oldSize.height();
|
|
|
|
x = parent->pos().x();
|
|
y = parent->pos().y();
|
|
break;
|
|
|
|
case LeftTop: //left top
|
|
width = oldSize.width() - cursorPos.x();
|
|
height = oldSize.height() - cursorPos.y();
|
|
|
|
x = parent->pos().x() - ( width - oldSize.width() );
|
|
y = parent->pos().y() - ( height - oldSize.height() );
|
|
break;
|
|
|
|
case RightTop: //right top
|
|
width = cursorPos.x();
|
|
height = oldSize.height() - cursorPos.y();
|
|
|
|
x = parent->pos().x();
|
|
y = parent->pos().y() - ( height - oldSize.height() );
|
|
|
|
break;
|
|
|
|
case LeftBottom: //left bottom
|
|
width = oldSize.width() - cursorPos.x();
|
|
height = cursorPos.y();
|
|
|
|
x = parent->pos().x() - ( width - oldSize.width() );
|
|
y = parent->pos().y();
|
|
|
|
break;
|
|
|
|
case RightBottom: //right bottom
|
|
width = cursorPos.x();
|
|
height = cursorPos.y();
|
|
|
|
x = parent->pos().x();
|
|
y = parent->pos().y();
|
|
break;
|
|
|
|
case Top: //top
|
|
width = oldSize.width();
|
|
height = oldSize.height() - cursorPos.y();
|
|
|
|
x = parent->pos().x();
|
|
y = parent->pos().y() - ( height - oldSize.height() );
|
|
break;
|
|
|
|
case Bottom: //bottom
|
|
width = oldSize.width();
|
|
height = cursorPos.y();
|
|
|
|
x = parent->pos().x();
|
|
y = parent->pos().y();
|
|
break;
|
|
}
|
|
|
|
if ( width > ( margins.left() + margins.right() ) &&
|
|
height > ( margins.top() + margins.bottom() ) )
|
|
{
|
|
parent->move ( x, y );
|
|
parent->resize ( width, height );
|
|
}
|
|
}
|
|
|
|
void QQtFramelessHelperPrivate::refreshMaximizedButton()
|
|
{
|
|
isMaximized = parent->windowState().testFlag ( Qt::WindowMaximized );
|
|
|
|
if ( buttonRestore != 0 )
|
|
{
|
|
buttonRestore->setVisible ( isMaximized );
|
|
}
|
|
|
|
if ( buttonMaximized != 0 )
|
|
{
|
|
buttonMaximized->setVisible ( !isMaximized );
|
|
}
|
|
}
|
|
|
|
bool QQtFramelessHelperPrivate::eventFilter ( QObject* obj, QEvent* event )
|
|
{
|
|
do
|
|
{
|
|
if ( event->type() == QEvent::WindowStateChange )
|
|
{
|
|
refreshMaximizedButton();
|
|
break;
|
|
}
|
|
|
|
if ( event->type() == QEvent::MouseButtonPress )
|
|
{
|
|
QMouseEvent* e = ( QMouseEvent* ) event;
|
|
|
|
// no move, no drag
|
|
if ( e->button() != Qt::LeftButton || isMaximized )
|
|
{
|
|
break;
|
|
}
|
|
|
|
checkPos();
|
|
|
|
if ( ( obj == parent || edgeWidgets.contains ( qobject_cast<QWidget*> ( obj ) ) ) && direction != None )
|
|
{
|
|
isMousePressed = true;
|
|
operation = MoveResize;
|
|
timer->stop();
|
|
return true;
|
|
}
|
|
|
|
if ( dragWidgets.contains ( qobject_cast<QWidget*> ( obj ) ) && direction == None )
|
|
{
|
|
isMousePressed = true;
|
|
operation = MoveDrag;
|
|
dragBasePoint = e->globalPos() - parent->pos();
|
|
timer->stop();
|
|
return true;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if ( event->type() == QEvent::MouseMove && isMousePressed )
|
|
{
|
|
QMouseEvent* e = ( QMouseEvent* ) event;
|
|
|
|
if ( operation == MoveDrag )
|
|
{
|
|
parent->move ( e->globalPos() - dragBasePoint );
|
|
return true;
|
|
}
|
|
|
|
if ( operation == MoveResize )
|
|
{
|
|
if ( obj != parent )
|
|
{
|
|
QWidget* w = qobject_cast<QWidget*> ( obj );
|
|
resize ( w->mapTo ( parent, e->pos() ) );
|
|
}
|
|
else
|
|
{
|
|
resize ( e->pos() );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if ( event->type() == QEvent::MouseButtonRelease )
|
|
{
|
|
QMouseEvent* e = ( QMouseEvent* ) event;
|
|
|
|
if ( e->button() == Qt::LeftButton && isMousePressed )
|
|
{
|
|
isMousePressed = false;
|
|
operation = MoveNone;
|
|
timer->start();
|
|
return true;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
} while ( false );
|
|
|
|
|
|
|
|
return QObject::eventFilter ( obj, event );
|
|
}
|