| 
									
										
										
										
											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-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-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) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint); | 
					
						
							|  |  |  |     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-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-01 10:37:14 +08:00
										 |  |  |             this, [ = ](){ m_graphicsView->setTransform(QTransform()); }); | 
					
						
							| 
									
										
										
										
											2019-09-30 23:02:44 +08:00
										 |  |  |     connect(m_bottomButtonGroup, &BottomButtonGroup::zoomInBtnClicked, | 
					
						
							| 
									
										
										
										
											2019-10-01 10:37:14 +08:00
										 |  |  |             this, [ = ](){ m_graphicsView->scale(1.25, 1.25); }); | 
					
						
							| 
									
										
										
										
											2019-09-30 23:02:44 +08:00
										 |  |  |     connect(m_bottomButtonGroup, &BottomButtonGroup::zoomOutBtnClicked, | 
					
						
							| 
									
										
										
										
											2019-10-01 10:37:14 +08:00
										 |  |  |             this, [ = ](){ m_graphicsView->scale(0.75, 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-09-30 23:02:44 +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-01 11:44:35 +08:00
										 |  |  | void MainWindow::adjustWindowSizeBySceneRect() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_graphicsView->transform().m11() < 1) { | 
					
						
							|  |  |  |         // 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-09-28 01:18:08 +08:00
										 |  |  | void MainWindow::mousePressEvent(QMouseEvent *event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (event->buttons() & Qt::LeftButton) { | 
					
						
							|  |  |  |         m_clickedOnWindow = true; | 
					
						
							|  |  |  |         m_oldMousePos = event->pos(); | 
					
						
							|  |  |  |         qDebug() << m_oldMousePos; | 
					
						
							|  |  |  |         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); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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
 | 
					
						
							|  |  |  |     // https://stackoverflow.com/questions/6649936/c-compiling-on-windows-and-linux-ifdef-switch
 | 
					
						
							|  |  |  |     // 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()); | 
					
						
							|  |  |  | } |