#include "qqtframelesshelperprivate.h" #include #include #include #include #include #include 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 ( obj ) ) ) && direction != None ) { isMousePressed = true; operation = MoveResize; timer->stop(); return true; } if ( dragWidgets.contains ( qobject_cast ( 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 ( 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 ); }