diff --git a/FinalProject/main.cpp b/FinalProject/main.cpp index fddc5d1..dd14077 100644 --- a/FinalProject/main.cpp +++ b/FinalProject/main.cpp @@ -1,13 +1,13 @@ -#include "mainwindow.h" #include +#include "mainwindow.h" + int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; - w.setWindowFlag(Qt::FramelessWindowHint); - w.setAttribute(Qt::WA_TranslucentBackground); w.setMouseTracking(true); + w.resize(900, 600); w.show(); return a.exec(); } diff --git a/FinalProject/mainwindow.cpp b/FinalProject/mainwindow.cpp index 8c67927..a132387 100644 --- a/FinalProject/mainwindow.cpp +++ b/FinalProject/mainwindow.cpp @@ -1,318 +1,29 @@ #include #include +#include #include "mainwindow.h" -#include "sceneviewer.h" +#include "pushbutton.h" #include "logger.h" #define MAX_MOUSE_MOVEMENT 300 MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent) + : FramelessWidget(20, parent) { - ui.setupUi(this); - ui.centralWidget->setMouseTracking(true); - - // Create and properly set real displayed window widget - _stretchLayout = new QVBoxLayout(this); - _stretchLayout->setContentsMargins(30, 30, 30, 30); - _windowWidget = new QWidget(this); - _windowWidget->setObjectName("windowWidget"); - _windowWidget->setMouseTracking(true); - _windowLayout = new QVBoxLayout(_windowWidget); - _windowLayout->setContentsMargins(0, 0, 0, 0); - _windowLayout->setSpacing(0); - _windowLayout->setAlignment(Qt::AlignTop); - _windowWidget->setLayout(_windowLayout); - _stretchLayout->addWidget(_windowWidget); - _windowWidget->show(); - ui.centralWidget->setLayout(_stretchLayout); - - // Set style sheet for window widget - QString windowWidgetStyleSheet = "QWidget#windowWidget{background-color:" + _backgroundColor.name() + ";border-radius:" + QString::number(_cornerRadius) + "px;}"; - _windowWidget->setStyleSheet(windowWidgetStyleSheet); - - // Set shadow for window widget - _windowShadow = new QGraphicsDropShadowEffect(_windowWidget); - _windowShadow->setBlurRadius(30); - _windowShadow->setColor(QColor(0, 0, 0)); - _windowShadow->setOffset(0, 0); - _windowWidget->setGraphicsEffect(_windowShadow); - - // Create title bar widget - _titleBar = new QWidget(_windowWidget); - _titleBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - _titleBar->setMouseTracking(true); - _titleBarLayout = new QHBoxLayout(_titleBar); - _titleBarLayout->setContentsMargins(18, 18, 18, 18); - _titleBarLayout->setSpacing(0); - _titleBarLayout->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - _titleBar->setLayout(_titleBarLayout); - _windowLayout->addWidget(_titleBar); - _titleBar->show(); - - // Create window control buttons container widget & its layout - _windowBtnWidget = new QWidget(_titleBar); - _windowBtnWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - _windowBtnLayout = new QHBoxLayout(_windowBtnWidget); - _windowBtnLayout->setContentsMargins(0, 0, 0, 0); - _windowBtnLayout->setSpacing(8); - _windowBtnWidget->setLayout(_windowBtnLayout); - _titleBarLayout->addWidget(_windowBtnWidget); - _windowBtnWidget->show(); - - // Create window control buttons - _minimizeBtn = new QPushButton(_windowBtnWidget); - _maximizeBtn = new QPushButton(_windowBtnWidget); - _closeBtn = new QPushButton(_windowBtnWidget); - - _minimizeBtn->setFixedSize(12, 12); - _maximizeBtn->setFixedSize(12, 12); - _closeBtn->setFixedSize(12, 12); - - _minimizeBtn->setStyleSheet("QPushButton{border-radius: 6px; background-color: #828282;}" - "QPushButton:hover{background-color: #e98b2a;}"); - _maximizeBtn->setStyleSheet("QPushButton{border-radius: 6px; background-color: #828282;}" - "QPushButton:hover{background-color: #2d6d4b;}"); - _closeBtn->setStyleSheet("QPushButton{border-radius: 6px; background-color: #828282;}" - "QPushButton:hover{background-color: #ab3b3a;}"); - - _windowBtnLayout->addWidget(_minimizeBtn); - _windowBtnLayout->addWidget(_maximizeBtn); - _windowBtnLayout->addWidget(_closeBtn); - _minimizeBtn->show(); - _maximizeBtn->show(); - _closeBtn->show(); - - // Connect window control buttons - connect(_minimizeBtn, &QPushButton::clicked, this, &MainWindow::showMinimized); - connect(_maximizeBtn, &QPushButton::clicked, this, [=]() {controlWindowScale(); }); - connect(_closeBtn, &QPushButton::clicked, qApp, &QApplication::quit); + PushButton* btn = new PushButton(new QLabel("Button"), this); + btn->setFixedSize(100, 100); + btn->move(100, 100); + btn->show(); + connect(btn, &PushButton::onClick, this, [=]() { + if (btn->isSelected()) { + btn->deselect(); + } + else { + btn->select(); + } + }); } MainWindow::~MainWindow() { -} - -void MainWindow::showEvent(QShowEvent* event) { - // Initialize window UI after window is shown - initializeWindowUI(); -} - -void MainWindow::initializeWindowUI() { - // Create a round cornered mask for window widget - QPainterPath path; - path.addRoundedRect(_windowWidget->rect(), _cornerRadius - 1, _cornerRadius - 1); - QRegion region(path.toFillPolygon().toPolygon()); - _windowWidget->setMask(region); - - // Create a border for window widget (in order to hide zigzagged edges) - _windowBorder = new QWidget(this); - _windowBorder->setObjectName("windowBorder"); - QString windowBorderStyleSheet = - "QWidget#windowBorder{background-color:#00FFFFFF;border:1.5px solid " + _borderColor.name() + ";border-radius:" + QString::number(_cornerRadius) + "px;}"; - _windowBorder->setStyleSheet(windowBorderStyleSheet); - _windowBorder->setAttribute(Qt::WA_TransparentForMouseEvents); - _windowBorder->move(_windowWidget->pos() - QPoint(1, 1)); - _windowBorder->resize(_windowWidget->size() + QSize(2, 2)); - _windowBorder->show(); -} - -void MainWindow::resizeEvent(QResizeEvent* event) { - // Resize window border - if (_windowBorder != nullptr) { - _windowBorder->move(_windowWidget->pos() - QPoint(1, 1)); - _windowBorder->resize(_windowWidget->size() + QSize(2, 2)); - } - - // Resize window mask - QPainterPath path; - path.addRoundedRect(_windowWidget->rect(), _cornerRadius - 1, _cornerRadius - 1); - QRegion region(path.toFillPolygon().toPolygon()); - _windowWidget->setMask(region); -} - -void MainWindow::controlWindowScale() { - if (!_maximized) { - _lastWindowGeometry = frameGeometry(); - - Logger::debug("Maximizing window:"); - Logger::debug("[+] current window position: " + std::to_string(x()) + ", " + std::to_string(y())); - Logger::debug("[+] current window size: " + std::to_string(width()) + ", " + std::to_string(height())); - Logger::debug("[+] current geometry: " + std::to_string(_lastWindowGeometry.x()) + ", " + std::to_string(_lastWindowGeometry.y()) + ", " + std::to_string(_lastWindowGeometry.width()) + ", " + std::to_string(_lastWindowGeometry.height())); - Logger::debug("[+] current window widget position: " + std::to_string(_windowWidget->x()) + ", " + std::to_string(_windowWidget->y())); - Logger::debug("[+] current window widget size: " + std::to_string(_windowWidget->width()) + ", " + std::to_string(_windowWidget->height())); - Logger::debug("[+] current window border position: " + std::to_string(_windowBorder->x()) + ", " + std::to_string(_windowBorder->y())); - Logger::debug("[+] current window border size: " + std::to_string(_windowBorder->width()) + ", " + std::to_string(_windowBorder->height())); - - _windowShadow->setEnabled(false); - _windowBorder->hide(); - QString windowWidgetStyleSheet = "QWidget#windowWidget{background-color:" + _backgroundColor.name() + ";}"; - _windowWidget->setStyleSheet(windowWidgetStyleSheet); - - _stretchLayout->setContentsMargins(0, 0, 0, 0); - - showMaximized(); - - QPainterPath path; - path.addRect(_windowWidget->rect()); - QRegion mask(path.toFillPolygon().toPolygon()); - _windowWidget->setMask(mask); - - _maximized = true; - } - else { - _stretchLayout->setContentsMargins(30, 30, 30, 30); - - showNormal(); - - resize(_lastWindowGeometry.size()); - move(_lastWindowGeometry.topLeft()); - - _windowShadow->setEnabled(true); - _windowBorder->show(); - QString windowWidgetStyleSheet = "QWidget#windowWidget{background-color:" + _backgroundColor.name() + ";border-radius:" + QString::number(_cornerRadius) + "px;}"; - _windowWidget->setStyleSheet(windowWidgetStyleSheet); - - QPainterPath path; - path.addRoundedRect(_windowWidget->rect(), _cornerRadius - 1, _cornerRadius - 1); - QRegion mask(path.toFillPolygon().toPolygon()); - _windowWidget->setMask(mask); - - Logger::debug("Restoring window:"); - Logger::debug("[+] current window position: " + std::to_string(x()) + ", " + std::to_string(y())); - Logger::debug("[+] current window size: " + std::to_string(width()) + ", " + std::to_string(height())); - Logger::debug("[+] current geometry: " + std::to_string(frameGeometry().x()) + ", " + std::to_string(frameGeometry().y()) + ", " + std::to_string(frameGeometry().width()) + ", " + std::to_string(frameGeometry().height())); - Logger::debug("[+] current window widget position: " + std::to_string(_windowWidget->x()) + ", " + std::to_string(_windowWidget->y())); - Logger::debug("[+] current window widget size: " + std::to_string(_windowWidget->width()) + ", " + std::to_string(_windowWidget->height())); - - _maximized = false; - } -} - -void MainWindow::updateMouseState(QMouseEvent* event) { - _mouseState = MOUSE_STATE_NONE; - if (_maximized) { - return; - } - // Set mouse state according to abs distance from window border - if (abs(event->globalPos().x() - (_windowWidget->frameGeometry().left() + frameGeometry().left())) < 5) { - _mouseState |= MOUSE_STATE_RESIZE_LEFT; - } - if (abs(event->globalPos().x() - (_windowWidget->frameGeometry().right() + frameGeometry().left())) < 5) { - _mouseState |= MOUSE_STATE_RESIZE_RIGHT; - } - if (abs(event->globalPos().y() - (_windowWidget->frameGeometry().top() + frameGeometry().top())) < 5) { - _mouseState |= MOUSE_STATE_RESIZE_TOP; - } - if (abs(event->globalPos().y() - (_windowWidget->frameGeometry().bottom() + frameGeometry().top())) < 5) { - _mouseState |= MOUSE_STATE_RESIZE_BOTTOM; - } - // Set cursor shape according to mouse state - switch (_mouseState) { - case MOUSE_STATE_RESIZE_LEFT: - case MOUSE_STATE_RESIZE_RIGHT: - setCursor(Qt::SizeHorCursor); - break; - case MOUSE_STATE_RESIZE_TOP: - case MOUSE_STATE_RESIZE_BOTTOM: - setCursor(Qt::SizeVerCursor); - break; - case MOUSE_STATE_RESIZE_LEFT | MOUSE_STATE_RESIZE_TOP: - case MOUSE_STATE_RESIZE_RIGHT | MOUSE_STATE_RESIZE_BOTTOM: - setCursor(Qt::SizeFDiagCursor); - break; - case MOUSE_STATE_RESIZE_LEFT | MOUSE_STATE_RESIZE_BOTTOM: - case MOUSE_STATE_RESIZE_RIGHT | MOUSE_STATE_RESIZE_TOP: - setCursor(Qt::SizeBDiagCursor); - break; - default: - setCursor(Qt::ArrowCursor); - break; - } -} - -void MainWindow::mousePressEvent(QMouseEvent* event) { - if (event->button() == Qt::LeftButton) { - _mousePressed = true; - _lastMousePosition = event->globalPos().toPointF(); - } -} - -void MainWindow::mouseReleaseEvent(QMouseEvent* event) { - _mousePressed = false; - QScreen* screen = QGuiApplication::screenAt(event->globalPos()); - Logger::debug("Current screen geometry:"); - Logger::debug("[+] screen position: " + std::to_string(screen->geometry().x()) + ", " + std::to_string(screen->geometry().y())); - Logger::debug("[+] screen size: " + std::to_string(screen->geometry().width()) + ", " + std::to_string(screen->geometry().height())); - if (abs(event->globalPos().y() - screen->geometry().top()) < 5) { - controlWindowScale(); - } - updateMouseState(event); -} - -void MainWindow::mouseMoveEvent(QMouseEvent* event) { - Logger::debug("Detected mouse move"); - Logger::debug("[+] mouse global position : " + std::to_string(event->globalPos().x()) + ", " + std::to_string(event->globalPos().y())); - Logger::debug("[+] window geometry: " + std::to_string(frameGeometry().x()) + ", " + std::to_string(frameGeometry().y()) + ", " + std::to_string(frameGeometry().width()) + ", " + std::to_string(frameGeometry().height())); - Logger::debug("[+] widget frame geometry: " + std::to_string(_windowWidget->frameGeometry().x()) + ", " + std::to_string(_windowWidget->frameGeometry().y())); - Logger::debug("[+] widget frame size: " + std::to_string(_windowWidget->frameGeometry().width()) + ", " + std::to_string(_windowWidget->frameGeometry().height())); -; if (event->buttons() == Qt::NoButton) { - _mousePressed = false; - } - if (abs(event->globalPos().x() - _lastMousePosition.x()) > MAX_MOUSE_MOVEMENT) { - // Maybe moving window across monitors, avoid window disappear - _lastMousePosition = event->globalPos().toPointF(); - } - if (abs(event->globalPos().y() - _lastMousePosition.y()) > MAX_MOUSE_MOVEMENT) { - // Maybe moving window across monitors, avoid window disappear - _lastMousePosition = event->globalPos().toPointF(); - } - if (!_mousePressed) { - updateMouseState(event); - } - else { - // Resize window according to mouse state - switch (_mouseState) { - case MOUSE_STATE_RESIZE_LEFT: - resize(frameGeometry().width() - event->globalPos().x() + frameGeometry().left() + _windowWidget->frameGeometry().left(), frameGeometry().height()); - move(event->globalPos().x() - _windowWidget->frameGeometry().left(), frameGeometry().top()); - break; - case MOUSE_STATE_RESIZE_RIGHT: - resize(event->globalPos().x() - frameGeometry().left() + _windowWidget->frameGeometry().left(), frameGeometry().height()); - break; - case MOUSE_STATE_RESIZE_TOP: - resize(frameGeometry().width(), frameGeometry().height() - event->globalPos().y() + frameGeometry().top() + _windowWidget->frameGeometry().top()); - move(frameGeometry().left(), event->globalPos().y() - _windowWidget->frameGeometry().top()); - break; - case MOUSE_STATE_RESIZE_BOTTOM: - resize(frameGeometry().width(), event->globalPos().y() - frameGeometry().top() + _windowWidget->frameGeometry().top()); - break; - case MOUSE_STATE_RESIZE_LEFT | MOUSE_STATE_RESIZE_TOP: - resize(frameGeometry().width() - event->globalPos().x() + frameGeometry().left() + _windowWidget->frameGeometry().left(), frameGeometry().height() - event->globalPos().y() + frameGeometry().top() + _windowWidget->frameGeometry().top()); - move(event->globalPos().x() - _windowWidget->frameGeometry().left(), event->globalPos().y() - _windowWidget->frameGeometry().top()); - break; - case MOUSE_STATE_RESIZE_LEFT | MOUSE_STATE_RESIZE_BOTTOM: - resize(frameGeometry().width() - event->globalPos().x() + frameGeometry().left() + _windowWidget->frameGeometry().left(), event->globalPos().y() + frameGeometry().top() - _windowWidget->frameGeometry().top()); - move(event->globalPos().x() - _windowWidget->frameGeometry().left(), frameGeometry().top()); - break; - case MOUSE_STATE_RESIZE_RIGHT | MOUSE_STATE_RESIZE_TOP: - resize(event->globalPos().x() - frameGeometry().left() + _windowWidget->frameGeometry().left(), frameGeometry().height() - event->globalPos().y() + frameGeometry().top() + _windowWidget->frameGeometry().top()); - move(frameGeometry().left(), event->globalPos().y() - _windowWidget->frameGeometry().top()); - break; - case MOUSE_STATE_RESIZE_RIGHT | MOUSE_STATE_RESIZE_BOTTOM: - resize(event->globalPos().x() - frameGeometry().left() + _windowWidget->frameGeometry().left(), event->globalPos().y() - frameGeometry().top() + _windowWidget->frameGeometry().top()); - break; - default: - if (_maximized) { - qreal wRatio = (qreal)event->pos().x() / (qreal)_windowWidget->width(); - controlWindowScale(); - move(event->globalPos().x() - _windowWidget->width() * wRatio, event->globalPos().y() - 52); - } - else { - move(frameGeometry().left() + event->globalPos().x() - _lastMousePosition.x(), frameGeometry().top() + event->globalPos().y() - _lastMousePosition.y()); - } - break; - } - _lastMousePosition = event->globalPos().toPointF(); - } -} +} \ No newline at end of file diff --git a/FinalProject/mainwindow.h b/FinalProject/mainwindow.h index 8376819..ddeca63 100644 --- a/FinalProject/mainwindow.h +++ b/FinalProject/mainwindow.h @@ -1,68 +1,12 @@ #pragma once -#include -#include -#include -#include -#include "ui_mainwindow.h" +#include "framelesswindow.h" -class MainWindow : public QMainWindow +class MainWindow : public FramelessWidget { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); - -private: - Ui::MainWindowClass ui; - -private: - // UI control variables - const int _cornerRadius = 20; - const QColor _backgroundColor = QColor(251, 251, 251); - const QColor _borderColor = QColor(104, 104, 104); - - // Window initialize - void initializeWindowUI(); - virtual void showEvent(QShowEvent* event) override; - - // Widget list - QVBoxLayout* _stretchLayout = nullptr; - QWidget* _windowWidget = nullptr; - QWidget* _windowBorder = nullptr; - QGraphicsDropShadowEffect* _windowShadow = nullptr; - QVBoxLayout* _windowLayout = nullptr; - QWidget* _titleBar = nullptr; - QHBoxLayout* _titleBarLayout = nullptr; - QWidget* _windowBtnWidget = nullptr; - QHBoxLayout* _windowBtnLayout = nullptr; - QPushButton* _minimizeBtn = nullptr; - QPushButton* _maximizeBtn = nullptr; - QPushButton* _closeBtn = nullptr; - QWidget* _objectList = nullptr; - QWidget* _settingsPannel = nullptr; - - // Window size control - bool _maximized = false; - QRect _lastWindowGeometry; - - virtual void resizeEvent(QResizeEvent* event) override; - void controlWindowScale(); - - // User interaction control - enum MOUSE_STATE { - MOUSE_STATE_NONE = 0, - MOUSE_STATE_RESIZE_LEFT = 1 << 0, - MOUSE_STATE_RESIZE_TOP = 1 << 1, - MOUSE_STATE_RESIZE_RIGHT = 1 << 2, - MOUSE_STATE_RESIZE_BOTTOM = 1 << 3 - }; - bool _mousePressed = false; - int _mouseState = MOUSE_STATE_NONE; - QPointF _lastMousePosition; - void updateMouseState(QMouseEvent* event); - virtual void mousePressEvent(QMouseEvent* event) override; - virtual void mouseReleaseEvent(QMouseEvent* event) override; - virtual void mouseMoveEvent(QMouseEvent* event) override; }; diff --git a/FinalProject/mainwindow.ui b/FinalProject/mainwindow.ui deleted file mode 100644 index 444ab27..0000000 --- a/FinalProject/mainwindow.ui +++ /dev/null @@ -1,23 +0,0 @@ - - - MainWindowClass - - - - 0 - 0 - 600 - 400 - - - - MainWindow - - - - - - - - -