#include "basewin.h" #include #include #include #include #include #include #include BaseWinBase::BaseWinBase(QWidget *that) : that(that) { that->setWindowFlag(Qt::FramelessWindowHint); that->setAttribute(Qt::WA_TranslucentBackground); that->setMouseTracking(true); auto layout = new QBoxLayout(QBoxLayout::TopToBottom, that); layout->setContentsMargins(8,8,8,8); layout->setSpacing(0); layout->addWidget(center = new QWidget()); center->installEventFilter(that); } QBoxLayout *BaseWinBase::addBtns(QBoxLayout *hBox) { if(hBox->count()==0) hBox->addStretch(); auto btn = new QPushButton(""); btn->setIcon(QIcon(":/imgs/macos-minimize.png")); btn->setIconSize(QSize(20,20)); btn->setStyleSheet("padding: 1;border:none;"); //btn->setProperty("ss", "min"); that->connect(btn, &QPushButton::clicked, that, &BaseWin::showMinimized); hBox->addWidget(btn); btn = new QPushButton(""); btn->setIcon(QIcon(":/imgs/close.png")); btn->setIconSize(QSize(20,20)); btn->setStyleSheet("padding: 1;border:none;"); //btn->setProperty("ss", "close"); that->connect(btn, &QPushButton::clicked, that, &BaseWin::close); hBox->addWidget(btn); return hBox; } void BaseWinBase::paintEvent() { QPainter painter(that); painter.setRenderHints(QPainter::Antialiasing); auto pal = that->palette(); auto back = pal.window(); bool isMax = that->isMaximized(); if(isMax) painter.fillRect(that->rect(), back); else { QPainterPath borderPath = QPainterPath(); borderPath.addRoundedRect(0.5, 0.5, that->width()-1, that->height()-1, borderRadius, borderRadius); painter.fillPath(borderPath, back); painter.strokePath(borderPath, isActive ? borderPenAct : borderPenUnact); } QString title = that->windowTitle(); if(! title.isEmpty()) { static const QPen penTitleUnact(Qt::gray); painter.setPen(isActive ? pal.windowText().color() : penTitleUnact); isMax ? painter.drawText(titlePos.x()-8, titlePos.y()-8, title) : painter.drawText(titlePos, title); } auto icon = that->windowIcon(); if(! icon.isNull()) isMax ? icon.paint(&painter, iconRect.translated(-8, -8)) : icon.paint(&painter, iconRect); } void transPos(QPoint &pos, QScreen *src, QScreen *dst) { auto ratio = src->devicePixelRatio(); if(ratio != 1) { auto geo = src->geometry(); pos.setX((pos.x() - geo.x()) * ratio + geo.x()); pos.setY((pos.y() - geo.y()) * ratio + geo.y()); } ratio = dst->devicePixelRatio(); if(ratio != 1) { auto geo = dst->geometry(); pos.setX((pos.x() - geo.x()) / ratio + geo.x()); pos.setY((pos.y() - geo.y()) / ratio + geo.y()); } } void BaseWinBase::mousePressEvent(QMouseEvent *e) { if(e->button() != Qt::LeftButton) return; setFrmSec(e->pos()); if(mFrmSec==Qt::TitleBarArea) {mPressRel = that->pos() - e->globalPos(); mSize = that->size();} else if(mFrmSec==Qt::TopSection || mFrmSec==Qt::LeftSection || mFrmSec==Qt::TopLeftSection) mPressRel = that->pos() - e->globalPos(); else if(mFrmSec==Qt::BottomRightSection) mPressRel = QPoint(that->width() - e->globalX(), that->height() - e->globalY()); else if(mFrmSec==Qt::RightSection ) mPressRel = QPoint(that->width() - e->globalX(), that->height() ); else if(mFrmSec==Qt::BottomSection ) mPressRel = QPoint(that->width() , that->height() - e->globalY()); else if(mFrmSec==Qt::TopRightSection ) mPressRel = that->geometry().topRight() - e->globalPos(); else if(mFrmSec==Qt::BottomLeftSection ) mPressRel = that->geometry().bottomLeft() - e->globalPos(); else if(mFrmSec==Qt::NoSection) mPressRel.setX(INT_MIN); } void BaseWinBase::mouseReleaseEvent(QMouseEvent *e) { if(e->button() != Qt::LeftButton) return; mPressRel.setX(INT_MIN); } void BaseWinBase::mouseMoveEvent(QMouseEvent *e) { if(e->buttons() & Qt::LeftButton) { if(mFrmSec==Qt::NoSection || mPressRel.x()==INT_MIN) return; if(that->isMaximized()) return; if(mFrmSec==Qt::TitleBarArea) { auto pos = e->globalPos(); auto screenMouse = QGuiApplication::screenAt(pos); if(screenMouse==0) return; auto screen = that->screen(); if(screenMouse!=screen) transPos(pos, screenMouse, screen); that->setGeometry(QRect(pos + mPressRel, mSize)); } else if(mFrmSec==Qt::BottomRightSection) that->resize(mPressRel.rx() + e->globalX(), mPressRel.ry() + e->globalY()); else if(mFrmSec==Qt::RightSection ) that->resize(mPressRel.rx() + e->globalX(), mPressRel.ry() ); else if(mFrmSec==Qt::BottomSection ) that->resize(mPressRel.rx() , mPressRel.ry() + e->globalY()); else { auto geo = that->geometry(); if(mFrmSec==Qt::LeftSection) geo.setLeft(e->globalX() + mPressRel.rx()); else if(mFrmSec==Qt::TopSection) geo.setTop(e->globalY() + mPressRel.ry()); else if(mFrmSec==Qt::TopLeftSection) geo.setTopLeft(e->globalPos() + mPressRel); else if(mFrmSec==Qt::TopRightSection) geo.setTopRight(e->globalPos() + mPressRel); else if(mFrmSec==Qt::BottomLeftSection) geo.setBottomLeft(e->globalPos() + mPressRel); that->setGeometry(geo); } } else setFrmSec(e->pos()); } void BaseWinBase::setFrmSec(const QPoint &pos) { if(that->isMaximized()) return; if(pos.y()<8) { if(pos.x()<16) setFrmSecIfNeed(Qt::TopLeftSection, Qt::SizeFDiagCursor); else if(pos.x()width()-16) setFrmSecIfNeed(Qt::TopSection, Qt::SizeVerCursor); else setFrmSecIfNeed(Qt::TopRightSection, Qt::SizeBDiagCursor); } else if(pos.y()>=that->height()-8) { if(pos.x()<16) setFrmSecIfNeed(Qt::BottomLeftSection, Qt::SizeBDiagCursor); else if(pos.x()width()-16) setFrmSecIfNeed(Qt::BottomSection, Qt::SizeVerCursor); else setFrmSecIfNeed(Qt::BottomRightSection, Qt::SizeFDiagCursor); } else if(pos.x()<8) { if(pos.y()<16) setFrmSecIfNeed(Qt::TopLeftSection, Qt::SizeFDiagCursor); else if(pos.y()height()-16) setFrmSecIfNeed(Qt::LeftSection, Qt::SizeHorCursor); else setFrmSecIfNeed(Qt::BottomLeftSection, Qt::SizeBDiagCursor); } else if(pos.x()>=that->width()-8) { if(pos.y()<16) setFrmSecIfNeed(Qt::TopRightSection, Qt::SizeBDiagCursor); else if(pos.y()height()-16) setFrmSecIfNeed(Qt::RightSection, Qt::SizeHorCursor); else setFrmSecIfNeed(Qt::BottomRightSection, Qt::SizeFDiagCursor); } else setFrmSecIfNeed(Qt::TitleBarArea, Qt::ArrowCursor); } void BaseWinBase::setFrmSecIfNeed(Qt::WindowFrameSection frmSec, Qt::CursorShape cursor) { if(mFrmSec==frmSec) return; mFrmSec = frmSec; if(cursor==Qt::ArrowCursor) that->unsetCursor(); else that->setCursor(cursor); } void BaseWinBase::leaveEvent() { setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor); mPressRel.setX(INT_MIN); } void BaseWinBase::mouseDoubleClickEvent(QMouseEvent *e) { if(e->y() > 32) return; mPressRel.setX(INT_MIN); mFrmSec = Qt::NoSection; if(that->isMaximized()) that->setWindowState(that->windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen)); else that->setWindowState((that->windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) | Qt::WindowMaximized); } bool BaseWinBase::eventFilter(QObject *watched, QEvent *e) { if(e->type()==QEvent::Enter && watched==center) { setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor); mPressRel.setX(INT_MIN); } return false; } void BaseWinBase::changeEvent(QEvent *e) { if(e->type()==QEvent::WindowStateChange) that->isMaximized() ? that->layout()->setContentsMargins(0,0,0,0) : that->layout()->setContentsMargins(8,8,8,8); } #ifdef _MSC_VER //MSVC编译器 #include bool BaseWinBase::nativeEvent(const QByteArray &eventType, void *message) { if(eventType=="windows_generic_MSG") { MSG *msg = (MSG*)message; if(msg->message==WM_NCACTIVATE) { isActive = msg->wParam; that->repaint(); } } return false; } #endif