2019-09-28 01:18:08 +08:00
|
|
|
#include "mainwindow.h"
|
|
|
|
|
2019-09-29 01:40:19 +08:00
|
|
|
#include "bottombuttongroup.h"
|
2019-09-28 01:18:08 +08:00
|
|
|
#include "graphicsview.h"
|
2019-10-03 17:57:14 +08:00
|
|
|
#include "navigatorview.h"
|
2019-09-29 15:52:35 +08:00
|
|
|
#include "graphicsscene.h"
|
2019-09-28 01:18:08 +08:00
|
|
|
|
|
|
|
#include <QMouseEvent>
|
|
|
|
#include <QMovie>
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QGraphicsTextItem>
|
2019-09-29 01:40:19 +08:00
|
|
|
#include <QApplication>
|
2019-09-29 15:52:35 +08:00
|
|
|
#include <QStyle>
|
|
|
|
#include <QScreen>
|
2019-10-03 11:00:28 +08:00
|
|
|
#include <QGraphicsOpacityEffect>
|
2019-09-29 01:40:19 +08:00
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#include <windows.h>
|
|
|
|
#endif // _WIN32
|
2019-09-28 01:18:08 +08:00
|
|
|
|
|
|
|
MainWindow::MainWindow(QWidget *parent) :
|
|
|
|
QMainWindow(parent)
|
|
|
|
{
|
2019-10-02 22:16:20 +08:00
|
|
|
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
|
2019-09-28 01:18:08 +08:00
|
|
|
this->setAttribute(Qt::WA_TranslucentBackground, true);
|
2019-09-29 22:18:38 +08:00
|
|
|
this->setMinimumSize(710, 530);
|
2019-10-01 11:44:35 +08:00
|
|
|
this->setWindowIcon(QIcon(":/icons/app-icon.svg"));
|
2019-09-28 01:18:08 +08:00
|
|
|
|
|
|
|
m_fadeOutAnimation = new QPropertyAnimation(this, "windowOpacity");
|
|
|
|
m_fadeOutAnimation->setDuration(300);
|
|
|
|
m_fadeOutAnimation->setStartValue(1);
|
|
|
|
m_fadeOutAnimation->setEndValue(0);
|
|
|
|
m_floatUpAnimation = new QPropertyAnimation(this, "geometry");
|
|
|
|
m_floatUpAnimation->setDuration(300);
|
|
|
|
m_floatUpAnimation->setEasingCurve(QEasingCurve::OutCirc);
|
|
|
|
m_exitAnimationGroup = new QParallelAnimationGroup;
|
|
|
|
m_exitAnimationGroup->addAnimation(m_fadeOutAnimation);
|
|
|
|
m_exitAnimationGroup->addAnimation(m_floatUpAnimation);
|
|
|
|
connect(m_exitAnimationGroup, &QParallelAnimationGroup::finished,
|
|
|
|
this, &QMainWindow::close);
|
|
|
|
|
2019-09-29 15:52:35 +08:00
|
|
|
GraphicsScene * scene = new GraphicsScene(this);
|
2019-09-28 01:18:08 +08:00
|
|
|
|
2019-10-01 10:37:14 +08:00
|
|
|
m_graphicsView = new GraphicsView(this);
|
|
|
|
m_graphicsView->setScene(scene);
|
|
|
|
this->setCentralWidget(m_graphicsView);
|
2019-09-28 01:18:08 +08:00
|
|
|
|
2019-10-03 17:57:14 +08:00
|
|
|
m_gv = new NavigatorView(this);
|
2019-10-04 21:34:20 +08:00
|
|
|
m_gv->setFixedSize(220, 160);
|
2019-10-03 17:57:14 +08:00
|
|
|
m_gv->setScene(scene);
|
2019-10-04 09:54:13 +08:00
|
|
|
m_gv->setMainView(m_graphicsView);
|
2019-10-03 17:57:14 +08:00
|
|
|
m_gv->fitInView(m_gv->sceneRect(), Qt::KeepAspectRatio);
|
|
|
|
|
|
|
|
connect(m_graphicsView, &GraphicsView::navigatorViewRequired,
|
|
|
|
this, [ = ](bool required, qreal angle){
|
|
|
|
m_gv->resetTransform();
|
|
|
|
m_gv->rotate(angle);
|
|
|
|
m_gv->fitInView(m_gv->sceneRect(), Qt::KeepAspectRatio);
|
|
|
|
m_gv->setVisible(required);
|
|
|
|
});
|
|
|
|
|
2019-10-04 09:54:13 +08:00
|
|
|
connect(m_graphicsView, &GraphicsView::viewportRectChanged,
|
|
|
|
m_gv, &NavigatorView::updateMainViewportRegion);
|
|
|
|
|
2019-10-01 10:37:14 +08:00
|
|
|
m_closeButton = new QPushButton(m_graphicsView);
|
2019-09-28 01:18:08 +08:00
|
|
|
m_closeButton->setFlat(true);
|
|
|
|
m_closeButton->setFixedSize(50, 50);
|
|
|
|
m_closeButton->setStyleSheet("QPushButton {"
|
|
|
|
"background: transparent;"
|
|
|
|
"}"
|
|
|
|
"QPushButton:hover {"
|
|
|
|
"background: red;"
|
|
|
|
"}");
|
|
|
|
|
|
|
|
connect(m_closeButton, &QAbstractButton::clicked,
|
|
|
|
this, &MainWindow::closeWindow);
|
2019-09-29 01:40:19 +08:00
|
|
|
|
|
|
|
m_bottomButtonGroup = new BottomButtonGroup(this);
|
2019-09-29 15:52:35 +08:00
|
|
|
|
2019-09-30 23:02:44 +08:00
|
|
|
connect(m_bottomButtonGroup, &BottomButtonGroup::resetToOriginalBtnClicked,
|
2019-10-02 16:04:50 +08:00
|
|
|
this, [ = ](){ m_graphicsView->resetScale(); });
|
2019-10-04 21:34:20 +08:00
|
|
|
connect(m_bottomButtonGroup, &BottomButtonGroup::toggleWindowMaximum,
|
|
|
|
this, [ = ](){
|
|
|
|
if (isMaximized()) {
|
|
|
|
showNormal();
|
|
|
|
} else {
|
|
|
|
showMaximized();
|
|
|
|
}
|
|
|
|
});
|
2019-09-30 23:02:44 +08:00
|
|
|
connect(m_bottomButtonGroup, &BottomButtonGroup::zoomInBtnClicked,
|
2019-10-02 16:04:50 +08:00
|
|
|
this, [ = ](){ m_graphicsView->zoomView(1.25); });
|
2019-09-30 23:02:44 +08:00
|
|
|
connect(m_bottomButtonGroup, &BottomButtonGroup::zoomOutBtnClicked,
|
2019-10-02 16:04:50 +08:00
|
|
|
this, [ = ](){ m_graphicsView->zoomView(0.75); });
|
2019-09-30 23:02:44 +08:00
|
|
|
connect(m_bottomButtonGroup, &BottomButtonGroup::toggleCheckerboardBtnClicked,
|
2019-10-01 10:37:14 +08:00
|
|
|
this, [ = ](){ m_graphicsView->toggleCheckerboard(); });
|
2019-10-02 14:31:24 +08:00
|
|
|
connect(m_bottomButtonGroup, &BottomButtonGroup::rotateRightBtnClicked,
|
|
|
|
this, [ = ](){
|
2019-10-02 16:04:50 +08:00
|
|
|
m_graphicsView->resetScale();
|
|
|
|
m_graphicsView->rotateView(90);
|
2019-10-02 14:31:24 +08:00
|
|
|
m_graphicsView->checkAndDoFitInView();
|
2019-10-03 17:57:14 +08:00
|
|
|
m_gv->setVisible(false);
|
2019-10-02 14:31:24 +08:00
|
|
|
});
|
2019-09-30 23:02:44 +08:00
|
|
|
|
2019-10-03 17:57:14 +08:00
|
|
|
m_btnGrpEffect = new QGraphicsOpacityEffect(this);
|
|
|
|
m_bribViewEffect = new QGraphicsOpacityEffect(this);
|
|
|
|
m_bottomButtonGroup->setGraphicsEffect(m_btnGrpEffect);
|
|
|
|
m_gv->setGraphicsEffect(m_bribViewEffect);
|
|
|
|
m_btnGrpOpacityAnimation = new QPropertyAnimation(m_btnGrpEffect, "opacity");
|
|
|
|
m_btnGrpOpacityAnimation->setDuration(300);
|
|
|
|
m_bribViewOpacityAnimation = new QPropertyAnimation(m_bribViewEffect, "opacity");
|
|
|
|
m_bribViewOpacityAnimation->setDuration(300);
|
2019-10-03 11:00:28 +08:00
|
|
|
|
2019-10-03 17:57:14 +08:00
|
|
|
m_btnGrpEffect->setOpacity(0);
|
|
|
|
m_bribViewEffect->setOpacity(0);
|
2019-10-03 11:00:28 +08:00
|
|
|
|
2019-10-01 11:44:35 +08:00
|
|
|
centerWindow();
|
2019-09-28 01:18:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
MainWindow::~MainWindow()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-10-01 10:37:14 +08:00
|
|
|
void MainWindow::showUrls(const QList<QUrl> &urls)
|
|
|
|
{
|
|
|
|
m_graphicsView->showFromUrlList(urls);
|
2019-10-03 17:57:14 +08:00
|
|
|
m_gv->fitInView(m_gv->sceneRect(), Qt::KeepAspectRatio);
|
2019-10-01 10:37:14 +08:00
|
|
|
}
|
|
|
|
|
2019-10-01 11:44:35 +08:00
|
|
|
void MainWindow::adjustWindowSizeBySceneRect()
|
|
|
|
{
|
2019-10-02 16:04:50 +08:00
|
|
|
if (m_graphicsView->scaleFactor() < 1) {
|
2019-10-01 11:44:35 +08:00
|
|
|
// if it scaled down by the resize policy:
|
|
|
|
QSize screenSize = qApp->screenAt(QCursor::pos())->availableSize();
|
|
|
|
QSize sceneSize = m_graphicsView->sceneRect().toRect().size();
|
|
|
|
QSize sceneSizeWithMargins = sceneSize + QSize(20, 20);
|
|
|
|
if (screenSize.expandedTo(sceneSize) == screenSize) {
|
|
|
|
// we can show the picture by increase the window size.
|
|
|
|
if (screenSize.expandedTo(sceneSizeWithMargins) == screenSize) {
|
|
|
|
this->resize(sceneSizeWithMargins);
|
|
|
|
} else {
|
|
|
|
this->resize(screenSize);
|
|
|
|
}
|
|
|
|
centerWindow();
|
|
|
|
} else {
|
|
|
|
// toggle maximum
|
|
|
|
showMaximized();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-29 01:40:19 +08:00
|
|
|
void MainWindow::showEvent(QShowEvent *event)
|
|
|
|
{
|
|
|
|
updateWidgetsPosition();
|
|
|
|
|
|
|
|
return QMainWindow::showEvent(event);
|
|
|
|
}
|
|
|
|
|
2019-10-03 11:00:28 +08:00
|
|
|
void MainWindow::enterEvent(QEvent *event)
|
|
|
|
{
|
2019-10-03 17:57:14 +08:00
|
|
|
m_btnGrpOpacityAnimation->stop();
|
|
|
|
m_btnGrpOpacityAnimation->setStartValue(m_btnGrpEffect->opacity());
|
|
|
|
m_btnGrpOpacityAnimation->setEndValue(1);
|
|
|
|
m_btnGrpOpacityAnimation->start();
|
|
|
|
|
|
|
|
m_bribViewOpacityAnimation->stop();
|
|
|
|
m_bribViewOpacityAnimation->setStartValue(m_bribViewEffect->opacity());
|
|
|
|
m_bribViewOpacityAnimation->setEndValue(1);
|
|
|
|
m_bribViewOpacityAnimation->start();
|
2019-10-03 11:00:28 +08:00
|
|
|
|
|
|
|
return QMainWindow::enterEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::leaveEvent(QEvent *event)
|
|
|
|
{
|
2019-10-03 17:57:14 +08:00
|
|
|
m_btnGrpOpacityAnimation->stop();
|
|
|
|
m_btnGrpOpacityAnimation->setStartValue(m_btnGrpEffect->opacity());
|
|
|
|
m_btnGrpOpacityAnimation->setEndValue(0);
|
|
|
|
m_btnGrpOpacityAnimation->start();
|
|
|
|
|
|
|
|
m_bribViewOpacityAnimation->stop();
|
|
|
|
m_bribViewOpacityAnimation->setStartValue(m_bribViewEffect->opacity());
|
|
|
|
m_bribViewOpacityAnimation->setEndValue(0);
|
|
|
|
m_bribViewOpacityAnimation->start();
|
2019-10-03 11:00:28 +08:00
|
|
|
|
|
|
|
return QMainWindow::leaveEvent(event);
|
|
|
|
}
|
|
|
|
|
2019-09-28 01:18:08 +08:00
|
|
|
void MainWindow::mousePressEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
if (event->buttons() & Qt::LeftButton) {
|
|
|
|
m_clickedOnWindow = true;
|
|
|
|
m_oldMousePos = event->pos();
|
2019-10-02 14:31:24 +08:00
|
|
|
qDebug() << m_oldMousePos << m_graphicsView->transform().m11()
|
2019-10-02 16:04:50 +08:00
|
|
|
<< m_graphicsView->transform().m22() << m_graphicsView->matrix().m12();
|
2019-09-28 01:18:08 +08:00
|
|
|
event->accept();
|
|
|
|
}
|
|
|
|
|
|
|
|
return QMainWindow::mousePressEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::mouseMoveEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
if (event->buttons() & Qt::LeftButton && m_clickedOnWindow) {
|
|
|
|
move(event->globalPos() - m_oldMousePos);
|
|
|
|
event->accept();
|
|
|
|
}
|
|
|
|
|
|
|
|
return QMainWindow::mouseMoveEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
m_clickedOnWindow = false;
|
|
|
|
|
|
|
|
return QMainWindow::mouseReleaseEvent(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
closeWindow();
|
|
|
|
|
|
|
|
return QMainWindow::mouseDoubleClickEvent(event);
|
|
|
|
}
|
|
|
|
|
2019-10-04 09:54:13 +08:00
|
|
|
void MainWindow::wheelEvent(QWheelEvent *event)
|
|
|
|
{
|
|
|
|
if (event->delta() > 0) {
|
|
|
|
m_graphicsView->zoomView(1.25);
|
|
|
|
} else {
|
|
|
|
m_graphicsView->zoomView(0.8);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-28 01:18:08 +08:00
|
|
|
void MainWindow::resizeEvent(QResizeEvent *event)
|
|
|
|
{
|
2019-09-29 01:40:19 +08:00
|
|
|
updateWidgetsPosition();
|
2019-09-28 01:18:08 +08:00
|
|
|
|
|
|
|
return QMainWindow::resizeEvent(event);
|
|
|
|
}
|
|
|
|
|
2019-09-29 01:40:19 +08:00
|
|
|
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
2019-10-03 17:57:14 +08:00
|
|
|
// https://stackoverflow.com/questions/43505580/qt-windows-resizable-frameless-window
|
2019-09-29 01:40:19 +08:00
|
|
|
// Too lazy to do this now.. just stackoverflow it and did a copy and paste..
|
|
|
|
Q_UNUSED(eventType);
|
|
|
|
MSG* msg = static_cast<MSG*>(message);
|
|
|
|
|
|
|
|
if (msg->message == WM_NCHITTEST) {
|
|
|
|
if (isMaximized()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*result = 0;
|
|
|
|
const LONG borderWidth = 8;
|
|
|
|
RECT winrect;
|
|
|
|
GetWindowRect(reinterpret_cast<HWND>(winId()), &winrect);
|
|
|
|
|
|
|
|
// must be short to correctly work with multiple monitors (negative coordinates)
|
|
|
|
short x = msg->lParam & 0x0000FFFF;
|
|
|
|
short y = (msg->lParam & 0xFFFF0000) >> 16;
|
|
|
|
|
|
|
|
bool resizeWidth = minimumWidth() != maximumWidth();
|
|
|
|
bool resizeHeight = minimumHeight() != maximumHeight();
|
|
|
|
if (resizeWidth) {
|
|
|
|
//left border
|
|
|
|
if (x >= winrect.left && x < winrect.left + borderWidth) {
|
|
|
|
*result = HTLEFT;
|
|
|
|
}
|
|
|
|
//right border
|
|
|
|
if (x < winrect.right && x >= winrect.right - borderWidth) {
|
|
|
|
*result = HTRIGHT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (resizeHeight) {
|
|
|
|
//bottom border
|
|
|
|
if (y < winrect.bottom && y >= winrect.bottom - borderWidth) {
|
|
|
|
*result = HTBOTTOM;
|
|
|
|
}
|
|
|
|
//top border
|
|
|
|
if (y >= winrect.top && y < winrect.top + borderWidth) {
|
|
|
|
*result = HTTOP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (resizeWidth && resizeHeight) {
|
|
|
|
//bottom left corner
|
|
|
|
if (x >= winrect.left && x < winrect.left + borderWidth &&
|
|
|
|
y < winrect.bottom && y >= winrect.bottom - borderWidth)
|
|
|
|
{
|
|
|
|
*result = HTBOTTOMLEFT;
|
|
|
|
}
|
|
|
|
//bottom right corner
|
|
|
|
if (x < winrect.right && x >= winrect.right - borderWidth &&
|
|
|
|
y < winrect.bottom && y >= winrect.bottom - borderWidth)
|
|
|
|
{
|
|
|
|
*result = HTBOTTOMRIGHT;
|
|
|
|
}
|
|
|
|
//top left corner
|
|
|
|
if (x >= winrect.left && x < winrect.left + borderWidth &&
|
|
|
|
y >= winrect.top && y < winrect.top + borderWidth)
|
|
|
|
{
|
|
|
|
*result = HTTOPLEFT;
|
|
|
|
}
|
|
|
|
//top right corner
|
|
|
|
if (x < winrect.right && x >= winrect.right - borderWidth &&
|
|
|
|
y >= winrect.top && y < winrect.top + borderWidth)
|
|
|
|
{
|
|
|
|
*result = HTTOPRIGHT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*result != 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
QWidget *action = QApplication::widgetAt(QCursor::pos());
|
|
|
|
if (action == this) {
|
|
|
|
*result = HTCAPTION;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
#else
|
2019-09-29 09:31:18 +08:00
|
|
|
return QMainWindow::nativeEvent(eventType, message, result);
|
2019-09-29 01:40:19 +08:00
|
|
|
#endif // _WIN32
|
|
|
|
}
|
|
|
|
|
2019-10-01 11:44:35 +08:00
|
|
|
void MainWindow::centerWindow()
|
|
|
|
{
|
|
|
|
this->setGeometry(
|
|
|
|
QStyle::alignedRect(
|
|
|
|
Qt::LeftToRight,
|
|
|
|
Qt::AlignCenter,
|
|
|
|
this->size(),
|
|
|
|
qApp->screenAt(QCursor::pos())->geometry()
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-09-28 01:18:08 +08:00
|
|
|
void MainWindow::closeWindow()
|
|
|
|
{
|
|
|
|
QRect windowRect(this->geometry());
|
|
|
|
m_floatUpAnimation->setStartValue(windowRect);
|
|
|
|
m_floatUpAnimation->setEndValue(windowRect.adjusted(0, -80, 0, 0));
|
|
|
|
m_floatUpAnimation->setStartValue(QRect(this->geometry().x(), this->geometry().y(), this->geometry().width(), this->geometry().height()));
|
|
|
|
m_floatUpAnimation->setEndValue(QRect(this->geometry().x(), this->geometry().y()-80, this->geometry().width(), this->geometry().height()));
|
|
|
|
m_exitAnimationGroup->start();
|
|
|
|
}
|
2019-09-29 01:40:19 +08:00
|
|
|
|
|
|
|
void MainWindow::updateWidgetsPosition()
|
|
|
|
{
|
|
|
|
m_closeButton->move(width() - m_closeButton->width(), 0);
|
|
|
|
m_bottomButtonGroup->move((width() - m_bottomButtonGroup->width()) / 2,
|
|
|
|
height() - m_bottomButtonGroup->height());
|
2019-10-03 17:57:14 +08:00
|
|
|
m_gv->move(width() - m_gv->width(), height() - m_gv->height());
|
2019-09-29 01:40:19 +08:00
|
|
|
}
|