diff --git a/examples/mainwindow/CMakeLists.txt b/examples/mainwindow/CMakeLists.txt index fd9bdf2..aa4b761 100644 --- a/examples/mainwindow/CMakeLists.txt +++ b/examples/mainwindow/CMakeLists.txt @@ -11,6 +11,8 @@ set(SOURCES ../images.qrc TitleBar.ui MainWindow.ui + mainwindow.h + mainwindow.cpp main.cpp ) diff --git a/examples/mainwindow/main.cpp b/examples/mainwindow/main.cpp index bb5055a..1e6981a 100644 --- a/examples/mainwindow/main.cpp +++ b/examples/mainwindow/main.cpp @@ -22,14 +22,8 @@ * SOFTWARE. */ -#include "../../framelesswindowsmanager.h" -#include "ui_MainWindow.h" -#include "ui_TitleBar.h" #include -#include -#include -#include -#include +#include "mainwindow.h" int main(int argc, char *argv[]) { @@ -56,58 +50,9 @@ int main(int argc, char *argv[]) QApplication application(argc, argv); - const auto mainWindow = new QMainWindow; - - Ui::MainWindow appMainWindow; - appMainWindow.setupUi(mainWindow); - - const auto widget = new QWidget; - Ui::TitleBar titleBarWidget; - titleBarWidget.setupUi(widget); - - QMenuBar *menuBar = mainWindow->menuBar(); - titleBarWidget.horizontalLayout->insertWidget(1, menuBar); - - mainWindow->setMenuWidget(widget); - - QObject::connect(mainWindow, &QMainWindow::windowIconChanged, titleBarWidget.iconButton, &QPushButton::setIcon); - QObject::connect(mainWindow, &QMainWindow::windowTitleChanged, titleBarWidget.titleLabel, &QLabel::setText); - QObject::connect(titleBarWidget.closeButton, &QPushButton::clicked, mainWindow, &QMainWindow::close); - QObject::connect(titleBarWidget.minimizeButton, &QPushButton::clicked, mainWindow, &QMainWindow::showMinimized); - QObject::connect(titleBarWidget.maximizeButton, &QPushButton::clicked, [mainWindow](){ - if (mainWindow->isMaximized() || mainWindow->isFullScreen()) { - mainWindow->showNormal(); - } else { - mainWindow->showMaximized(); - } - }); -#if 0 - QObject::connect(mainWindow, &QMainWindow::windowStateChanged, [mainWindow, titleBarWidget](){ - titleBarWidget.maximizeButton->setChecked(mainWindow->isMaximized()); - titleBarWidget.maximizeButton->setToolTip(mainWindow->isMaximized() ? QObject::tr("Restore") : QObject::tr("Maximize")); - }); - QObject::connect(titleBarWidget.iconButton, &QPushButton::clicked, mainWindow, &QMainWindow::displaySystemMenu); -#endif - - QStyleOption option; - option.initFrom(mainWindow); - const QIcon icon = mainWindow->style()->standardIcon(QStyle::SP_ComputerIcon, &option); - mainWindow->setWindowIcon(icon); - mainWindow->setWindowTitle(QObject::tr("Hello, World!")); - - mainWindow->createWinId(); // Qt's internal function, make sure it's a top level window. - const QWindow *win = mainWindow->windowHandle(); - - FramelessWindowsManager::addWindow(win); - FramelessWindowsManager::addIgnoreObject(win, titleBarWidget.iconButton); - FramelessWindowsManager::addIgnoreObject(win, titleBarWidget.minimizeButton); - FramelessWindowsManager::addIgnoreObject(win, titleBarWidget.maximizeButton); - FramelessWindowsManager::addIgnoreObject(win, titleBarWidget.closeButton); - FramelessWindowsManager::addIgnoreObject(win, appMainWindow.menubar); - - mainWindow->resize(800, 600); - - mainWindow->show(); + MainWindow mainWindow; + mainWindow.resize(800, 600); + mainWindow.show(); return QApplication::exec(); } diff --git a/examples/mainwindow/mainwindow.cpp b/examples/mainwindow/mainwindow.cpp new file mode 100644 index 0000000..c8e510f --- /dev/null +++ b/examples/mainwindow/mainwindow.cpp @@ -0,0 +1,135 @@ +/* + * MIT License + * + * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "mainwindow.h" +#include +#include "../../framelesswindowsmanager.h" +#include "../../utilities.h" + +MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) +{ + appMainWindow = new Ui::MainWindow; + appMainWindow->setupUi(this); + + const auto widget = new QWidget(this); + titleBarWidget = new Ui::TitleBar; + titleBarWidget->setupUi(widget); + + QMenuBar *mb = menuBar(); + titleBarWidget->horizontalLayout->insertWidget(1, mb); + + setMenuWidget(widget); + + connect(this, &MainWindow::windowIconChanged, titleBarWidget->iconButton, &QPushButton::setIcon); + connect(this, &MainWindow::windowTitleChanged, titleBarWidget->titleLabel, &QLabel::setText); + connect(titleBarWidget->closeButton, &QPushButton::clicked, this, &MainWindow::close); + connect(titleBarWidget->minimizeButton, &QPushButton::clicked, this, &MainWindow::showMinimized); + connect(titleBarWidget->maximizeButton, &QPushButton::clicked, [this](){ + if (isMaximized() || isFullScreen()) { + showNormal(); + } else { + showMaximized(); + } + }); + connect(this, &MainWindow::windowStateChanged, [this](){ + titleBarWidget->maximizeButton->setChecked(isMaximized()); + titleBarWidget->maximizeButton->setToolTip(isMaximized() ? tr("Restore") : tr("Maximize")); + }); + //connect(titleBarWidget->iconButton, &QPushButton::clicked, this, &MainWindow::displaySystemMenu); +} + +MainWindow::~MainWindow() +{ + if (titleBarWidget) { + delete titleBarWidget; + titleBarWidget = nullptr; + } + if (appMainWindow) { + delete appMainWindow; + appMainWindow = nullptr; + } +} + +void MainWindow::showEvent(QShowEvent *event) +{ + QMainWindow::showEvent(event); + static bool inited = false; + if (!inited) { + const auto win = windowHandle(); + if (win) { + FramelessWindowsManager::addWindow(win); + FramelessWindowsManager::addIgnoreObject(win, titleBarWidget->iconButton); + FramelessWindowsManager::addIgnoreObject(win, titleBarWidget->minimizeButton); + FramelessWindowsManager::addIgnoreObject(win, titleBarWidget->maximizeButton); + FramelessWindowsManager::addIgnoreObject(win, titleBarWidget->closeButton); + FramelessWindowsManager::addIgnoreObject(win, appMainWindow->menubar); + inited = true; + } + } +} + +void MainWindow::changeEvent(QEvent *event) +{ + QWidget::changeEvent(event); + bool shouldUpdate = false; + if (event->type() == QEvent::WindowStateChange) { + if (isMaximized() || isFullScreen()) { + layout()->setContentsMargins(0, 0, 0, 0); + } else if (!isMinimized()) { + layout()->setContentsMargins(1, 1, 1, 1); + } + shouldUpdate = true; + Q_EMIT windowStateChanged(); + } else if (event->type() == QEvent::ActivationChange) { + shouldUpdate = true; + } + if (shouldUpdate) { + update(); + } +} + +void MainWindow::paintEvent(QPaintEvent *event) +{ + QMainWindow::paintEvent(event); + if (windowState() == Qt::WindowNoState) { + QPainter painter(this); + const int w = width(); + const int h = height(); +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + using BorderLines = QList; +#else + using BorderLines = QVector; +#endif + const BorderLines lines = { + {0, 0, w, 0}, + {w - 1, 0, w - 1, h}, + {w, h - 1, 0, h - 1}, + {0, h, 0, 0} + }; + painter.save(); + painter.setPen({Utilities::getNativeWindowFrameColor(), 1}); + painter.drawLines(lines); + painter.restore(); + } +} diff --git a/examples/mainwindow/mainwindow.h b/examples/mainwindow/mainwindow.h new file mode 100644 index 0000000..3da1d9b --- /dev/null +++ b/examples/mainwindow/mainwindow.h @@ -0,0 +1,50 @@ +/* + * MIT License + * + * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once + +#include +#include "ui_MainWindow.h" +#include "ui_TitleBar.h" + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = {}); + ~MainWindow() override; + +protected: + void showEvent(QShowEvent *event) override; + void paintEvent(QPaintEvent *event) override; + void changeEvent(QEvent *event) override; + +Q_SIGNALS: + void windowStateChanged(); + +private: + Ui::TitleBar *titleBarWidget = nullptr; + Ui::MainWindow *appMainWindow = nullptr; +}; diff --git a/examples/mainwindow/mainwindow.pro b/examples/mainwindow/mainwindow.pro index b71f743..bcc3fa6 100644 --- a/examples/mainwindow/mainwindow.pro +++ b/examples/mainwindow/mainwindow.pro @@ -1,6 +1,7 @@ TARGET = MainWindow TEMPLATE = app QT += widgets -SOURCES += main.cpp +HEADERS += mainwindow.h +SOURCES += mainwindow.cpp main.cpp FORMS += TitleBar.ui MainWindow.ui include($$PWD/../common.pri) diff --git a/examples/widget/widget.h b/examples/widget/widget.h index 9c66849..c07b00b 100644 --- a/examples/widget/widget.h +++ b/examples/widget/widget.h @@ -34,7 +34,6 @@ QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT - Q_DISABLE_COPY_MOVE(Widget) public: explicit Widget(QWidget *parent = nullptr);