130 lines
6.2 KiB
C++
130 lines
6.2 KiB
C++
#include "basewin.h"
|
|
#include <QLayout>
|
|
#include <QMouseEvent>
|
|
#include <QPainter>
|
|
#include <QPainterPath>
|
|
#include <QIcon>
|
|
#include <windows.h>
|
|
|
|
BaseWin::BaseWin(QWidget *parent) : QWidget(parent){
|
|
setWindowFlag(Qt::FramelessWindowHint);
|
|
setAttribute(Qt::WA_TranslucentBackground);
|
|
setMouseTracking(true);
|
|
auto layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
|
|
layout->setContentsMargins(8,8,8,8);
|
|
layout->setSpacing(0);
|
|
layout->addWidget(center = new QWidget());
|
|
center->installEventFilter(this);
|
|
}
|
|
|
|
void BaseWin::paintEvent(QPaintEvent *e) {
|
|
QWidget::paintEvent(e);
|
|
QPainter painter(this);
|
|
painter.setRenderHints(QPainter::Antialiasing);
|
|
if(isMaximized()) painter.fillRect(rect(), palette().window());
|
|
else {
|
|
QPainterPath path = QPainterPath();
|
|
path.addRoundedRect(0.5, 0.5, width()-1, height()-1, roundRadius, roundRadius);
|
|
painter.fillPath(path, palette().window());
|
|
painter.strokePath(path, isActive ? borderPenAct : borderPenUnact);
|
|
}
|
|
QString title = windowTitle();
|
|
if(! title.isNull()){
|
|
static const QPen penTitleAct(Qt::black);
|
|
static const QPen penTitleUnact(Qt::darkGray);
|
|
painter.setPen(isActive ? penTitleAct : penTitleUnact);
|
|
isMaximized() ? painter.drawText(titlePos.x()-8, titlePos.y()-8, title) : painter.drawText(titlePos, title);
|
|
}
|
|
if(! icon.isNull()) isMaximized() ? painter.drawPixmap(iconPos.x()-8, iconPos.y()-8, icon) : painter.drawPixmap(iconPos, icon);
|
|
}
|
|
|
|
void BaseWin::mousePressEvent(QMouseEvent *e) {
|
|
if(e->button() != Qt::LeftButton) return;
|
|
setFrmSec(e->pos());
|
|
if(mFrmSec==Qt::TitleBarArea || mFrmSec==Qt::TopSection || mFrmSec==Qt::LeftSection || mFrmSec==Qt::TopLeftSection) mPressRel = pos() - e->globalPos();
|
|
else if(mFrmSec==Qt::BottomRightSection) mPressRel = QPoint(width() - e->globalX(), height() - e->globalY());
|
|
else if(mFrmSec==Qt::RightSection ) mPressRel = QPoint(width() - e->globalX(), height() );
|
|
else if(mFrmSec==Qt::BottomSection ) mPressRel = QPoint(width() , height() - e->globalY());
|
|
else if(mFrmSec==Qt::TopRightSection ) mPressRel = geometry().topRight() - e->globalPos();
|
|
else if(mFrmSec==Qt::BottomLeftSection ) mPressRel = geometry().bottomLeft() - e->globalPos();
|
|
else if(mFrmSec==Qt::NoSection) mPressRel.setX(INT_MAX);
|
|
}
|
|
void BaseWin::mouseReleaseEvent(QMouseEvent *e) {
|
|
if(e->button() == Qt::LeftButton) mPressRel.setX(INT_MAX);
|
|
}
|
|
void BaseWin::mouseMoveEvent(QMouseEvent *e) {
|
|
if(e->buttons() & Qt::LeftButton) {
|
|
if(mFrmSec==Qt::NoSection || mPressRel.x()==INT_MAX) return;
|
|
if(isMaximized()) return;
|
|
if(mFrmSec==Qt::TitleBarArea) move(mPressRel + e->globalPos());
|
|
else if(mFrmSec==Qt::BottomRightSection) resize(mPressRel.rx() + e->globalX(), mPressRel.ry() + e->globalY());
|
|
else if(mFrmSec==Qt::RightSection ) resize(mPressRel.rx() + e->globalX(), mPressRel.ry() );
|
|
else if(mFrmSec==Qt::BottomSection ) resize(mPressRel.rx() , mPressRel.ry() + e->globalY());
|
|
else {
|
|
auto geo = geometry();
|
|
if(mFrmSec==Qt::LeftSection) geo.setLeft(mPressRel.rx() + e->globalX());
|
|
else if(mFrmSec==Qt::TopSection) geo.setTop(mPressRel.ry() + e->globalY());
|
|
else if(mFrmSec==Qt::TopLeftSection) geo.setTopLeft(mPressRel + e->globalPos());
|
|
else if(mFrmSec==Qt::TopRightSection) geo.setTopRight(mPressRel + e->globalPos());
|
|
else if(mFrmSec==Qt::BottomLeftSection) geo.setBottomLeft(mPressRel + e->globalPos());
|
|
setGeometry(geo);
|
|
}
|
|
} else setFrmSec(e->pos());
|
|
}
|
|
void BaseWin::setFrmSec(const QPoint &pos) {
|
|
if(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()>=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()>=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 BaseWin::setFrmSecIfNeed(Qt::WindowFrameSection frmSec, Qt::CursorShape cursor) {
|
|
if(mFrmSec==frmSec) return;
|
|
mFrmSec = frmSec;
|
|
if(cursor==Qt::ArrowCursor) unsetCursor();
|
|
else setCursor(cursor);
|
|
}
|
|
void BaseWin::leaveEvent(QEvent *) {
|
|
setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor);
|
|
mPressRel.setX(INT_MAX);
|
|
}
|
|
bool BaseWin::eventFilter(QObject *watched, QEvent *e) {
|
|
if(e->type()==QEvent::Enter && watched==center) {
|
|
setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor);
|
|
mPressRel.setX(INT_MAX);
|
|
}
|
|
return false;
|
|
}
|
|
void BaseWin::changeEvent(QEvent *e) {
|
|
if(e->type()==QEvent::WindowStateChange) isMaximized() ? layout()->setContentsMargins(0,0,0,0) : layout()->setContentsMargins(8,8,8,8);
|
|
}
|
|
void BaseWin::mouseDoubleClickEvent(QMouseEvent *e) {
|
|
if(e->y()>32) return;
|
|
if(isMaximized()) setWindowState(windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen));
|
|
else setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowFullScreen)) | Qt::WindowMaximized);
|
|
}
|
|
|
|
bool BaseWin::nativeEvent(const QByteArray &eventType, void *message, long *){
|
|
if(eventType=="windows_generic_MSG"){
|
|
MSG *msg = (MSG*)message;
|
|
if(msg->message==WM_NCACTIVATE){
|
|
isActive = msg->wParam;
|
|
update();
|
|
}
|
|
}
|
|
return false;
|
|
}
|