diff --git a/CMakeLists.txt b/CMakeLists.txt index 60b03ca..aeaaad2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ set(CMAKE_AUTOUIC ON) # set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTORCC ON) -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}") -include(QWindowKit) +# set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}") +# include(QWindowKit) find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets OpenGLWidgets Network SerialPort) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4914412..aa7bf2b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,14 +17,13 @@ qt6_add_resources(VideoClient "resources" ) - set(3RDPARTY_DIR ${CMAKE_CURRENT_LIST_DIR}/3rdparty) set(FFMPEG_DIR ${3RDPARTY_DIR}/ffmpeg) - +# add_subdirectory(shared) add_subdirectory(video) add_subdirectory(3rdparty) -add_subdirectory(shared) + target_link_libraries(VideoClient PRIVATE @@ -35,8 +34,8 @@ target_link_libraries(VideoClient Qt6::Network Qt6::SerialPort video - QWindowKit::Widgets - WidgetFrame + # QWindowKit::Widgets + # WidgetFrame ) # 指定头文件路径 target_include_directories(VideoClient PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 980c77e..cf7ea95 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,24 +1,30 @@ #include "mainwindow.h" -#include -#include +// #include +// #include #include +#include #include "ui_mainwindow.h" -#include "widgetframe/windowbar.h" -#include "widgetframe/windowbutton.h" +// #include "widgetframe/windowbar.h" +// #include "widgetframe/windowbutton.h" +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +#include +#else +#include +#endif -MainWindow::MainWindow(QWidget* parent) +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); this->setWindowTitle("载荷视频播放软件"); - // windowAgent = new QWK::WidgetWindowAgent(this); - // windowAgent->setup(this); - // auto windowBar = new QWK::WindowBar(); - // auto iconButton = new QWK::WindowButton(); /* + auto windowAgent = new QWK::WidgetWindowAgent(this); + windowAgent->setup(this); + auto windowBar = new QWK::WindowBar(); + auto iconButton = new QWK::WindowButton(); iconButton->setObjectName(QStringLiteral("icon-button")); iconButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); @@ -43,8 +49,9 @@ MainWindow::MainWindow(QWidget* parent) windowBar->setMaxButton(maxButton); windowBar->setCloseButton(closeButton); windowAgent->setTitleBar(windowBar); -*/ - + setMenuWidget(windowBar); + // windowAgent->setHitTestVisible(windowBar->menuBar(), true); + */ // apply the qss QFile qssfile(":/Qss/qss.qss"); if (qssfile.open(QFile::ReadOnly)) { @@ -115,3 +122,198 @@ void MainWindow::showMessageSlots(QString message, int type) { m_notifyManager->notify(message, "", type, 3000); } } + +/* +void MainWindow::installWindowAgent() { + // 1. Setup window agent + windowAgent = new QWK::WidgetWindowAgent(this); + windowAgent->setup(this); + + // 2. Construct your title bar + auto menuBar = [this]() { + auto menuBar = new QMenuBar(this); + + // Virtual menu + auto file = new QMenu(tr("File(&F)"), menuBar); + file->addAction(new QAction(tr("New(&N)"), menuBar)); + file->addAction(new QAction(tr("Open(&O)"), menuBar)); + file->addSeparator(); + + auto edit = new QMenu(tr("Edit(&E)"), menuBar); + edit->addAction(new QAction(tr("Undo(&U)"), menuBar)); + edit->addAction(new QAction(tr("Redo(&R)"), menuBar)); + + // Theme action + auto darkAction = new QAction(tr("Enable dark theme"), menuBar); + darkAction->setCheckable(true); + // connect(darkAction, &QAction::triggered, this, [this](bool checked) { + // loadStyleSheet(checked ? Dark : Light); // + // }); + // connect(this, &MainWindow::themeChanged, darkAction, + // [this, darkAction]() { + // darkAction->setChecked(currentTheme == Dark); // + // }); + + auto noneAction = new QAction(tr("None"), menuBar); + noneAction->setData(QStringLiteral("none")); + noneAction->setCheckable(true); + noneAction->setChecked(true); + + auto dwmBlurAction = new QAction(tr("Enable DWM blur"), menuBar); + dwmBlurAction->setData(QStringLiteral("dwm-blur")); + dwmBlurAction->setCheckable(true); + + auto acrylicAction = + new QAction(tr("Enable acrylic material"), menuBar); + acrylicAction->setData(QStringLiteral("acrylic-material")); + acrylicAction->setCheckable(true); + + auto micaAction = new QAction(tr("Enable mica"), menuBar); + micaAction->setData(QStringLiteral("mica")); + micaAction->setCheckable(true); + + auto micaAltAction = new QAction(tr("Enable mica alt"), menuBar); + micaAltAction->setData(QStringLiteral("mica-alt")); + micaAltAction->setCheckable(true); + + auto winStyleGroup = new QActionGroup(menuBar); + winStyleGroup->addAction(noneAction); + winStyleGroup->addAction(dwmBlurAction); + winStyleGroup->addAction(acrylicAction); + winStyleGroup->addAction(micaAction); + winStyleGroup->addAction(micaAltAction); + // connect(winStyleGroup, &QActionGroup::triggered, this, + // [this, winStyleGroup](QAction *action) { + // // Unset all custom style attributes first, otherwise the + // // style will not display correctly + // for (const QAction *_act : winStyleGroup->actions()) { + // const QString data = _act->data().toString(); + // if (data.isEmpty() || data == QStringLiteral("none")) + // { + // continue; + // } + // windowAgent->setWindowAttribute(data, false); + // } + // const QString data = action->data().toString(); + // if (data == QStringLiteral("none")) { + // setProperty("custom-style", false); + // } else if (!data.isEmpty()) { + // windowAgent->setWindowAttribute(data, true); + // setProperty("custom-style", true); + // } + // style()->polish(this); + // }); + + // Real menu + auto settings = new QMenu(tr("Settings(&S)"), menuBar); + settings->addAction(darkAction); + + settings->addSeparator(); + settings->addAction(noneAction); + settings->addAction(dwmBlurAction); + settings->addAction(acrylicAction); + settings->addAction(micaAction); + settings->addAction(micaAltAction); + + menuBar->addMenu(file); + menuBar->addMenu(edit); + menuBar->addMenu(settings); + return menuBar; + }(); + menuBar->setObjectName(QStringLiteral("win-menu-bar")); + + auto titleLabel = new QLabel(); + titleLabel->setAlignment(Qt::AlignCenter); + titleLabel->setObjectName(QStringLiteral("win-title-label")); + +#ifndef Q_OS_MAC + auto iconButton = new QWK::WindowButton(); + iconButton->setObjectName(QStringLiteral("icon-button")); + iconButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + auto pinButton = new QWK::WindowButton(); + pinButton->setCheckable(true); + pinButton->setObjectName(QStringLiteral("pin-button")); + pinButton->setProperty("system-button", true); + pinButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + auto minButton = new QWK::WindowButton(); + minButton->setObjectName(QStringLiteral("min-button")); + minButton->setProperty("system-button", true); + minButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + auto maxButton = new QWK::WindowButton(); + maxButton->setCheckable(true); + maxButton->setObjectName(QStringLiteral("max-button")); + maxButton->setProperty("system-button", true); + maxButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + auto closeButton = new QWK::WindowButton(); + closeButton->setObjectName(QStringLiteral("close-button")); + closeButton->setProperty("system-button", true); + closeButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); +#endif + + auto windowBar = new QWK::WindowBar(); +#ifndef Q_OS_MAC + windowBar->setIconButton(iconButton); + windowBar->setPinButton(pinButton); + windowBar->setMinButton(minButton); + windowBar->setMaxButton(maxButton); + windowBar->setCloseButton(closeButton); +#endif + windowBar->setMenuBar(menuBar); + windowBar->setTitleLabel(titleLabel); + windowBar->setHostWidget(this); + + windowAgent->setTitleBar(windowBar); +#ifndef Q_OS_MAC + windowAgent->setHitTestVisible(pinButton, true); + windowAgent->setSystemButton(QWK::WindowAgentBase::WindowIcon, iconButton); + windowAgent->setSystemButton(QWK::WindowAgentBase::Minimize, minButton); + windowAgent->setSystemButton(QWK::WindowAgentBase::Maximize, maxButton); + windowAgent->setSystemButton(QWK::WindowAgentBase::Close, closeButton); +#endif + windowAgent->setHitTestVisible(menuBar, true); + +#ifdef Q_OS_MAC + windowAgent->setSystemButtonAreaCallback([](const QSize &size) { + static constexpr const int width = 75; + return QRect(QPoint(size.width() - width, 0), + QSize(width, size.height())); // + }); +#endif + + setMenuWidget(windowBar); + +#ifndef Q_OS_MAC + connect(windowBar, &QWK::WindowBar::pinRequested, this, + [this, pinButton](bool pin) { + if (isHidden() || isMinimized() || isMaximized() || + isFullScreen()) { + return; + } + setWindowFlag(Qt::WindowStaysOnTopHint, pin); + show(); + pinButton->setChecked(pin); + }); + connect(windowBar, &QWK::WindowBar::minimizeRequested, this, + &QWidget::showMinimized); + connect(windowBar, &QWK::WindowBar::maximizeRequested, this, + [this, maxButton](bool max) { + if (max) { + showMaximized(); + } else { + showNormal(); + } + + // It's a Qt issue that if a QAbstractButton::clicked triggers a + // window's maximization, the button remains to be hovered until + // the mouse move. As a result, we need to manually send leave + // events to the button. + // emulateLeaveEvent(maxButton); + }); + connect(windowBar, &QWK::WindowBar::closeRequested, this, &QWidget::close); +#endif +} +*/ diff --git a/src/mainwindow.h b/src/mainwindow.h index 3d8769c..c26930d 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -8,6 +8,11 @@ #include "commandwidget.h" #include "global.h" +namespace QWK { +class WidgetWindowAgent; +class StyleAgent; +} // namespace QWK + QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; @@ -28,8 +33,11 @@ private: void showMessageSlots(QString message, int type); + // void installWindowAgent(); + private: Ui::MainWindow *ui; + // QWK::WidgetWindowAgent *windowAgent; NotifyManager *m_notifyManager = nullptr; }; #endif // MAINWINDOW_H diff --git a/src/shared/widgetframe/resources/app/example.icns b/src/shared/resources/app/example.icns similarity index 100% rename from src/shared/widgetframe/resources/app/example.icns rename to src/shared/resources/app/example.icns diff --git a/src/shared/widgetframe/resources/app/example.ico b/src/shared/resources/app/example.ico similarity index 100% rename from src/shared/widgetframe/resources/app/example.ico rename to src/shared/resources/app/example.ico diff --git a/src/shared/widgetframe/resources/app/example.png b/src/shared/resources/app/example.png similarity index 100% rename from src/shared/widgetframe/resources/app/example.png rename to src/shared/resources/app/example.png diff --git a/src/shared/widgetframe/resources/shared.qrc b/src/shared/resources/shared.qrc similarity index 100% rename from src/shared/widgetframe/resources/shared.qrc rename to src/shared/resources/shared.qrc diff --git a/src/shared/widgetframe/resources/window-bar/close.svg b/src/shared/resources/window-bar/close.svg similarity index 100% rename from src/shared/widgetframe/resources/window-bar/close.svg rename to src/shared/resources/window-bar/close.svg diff --git a/src/shared/widgetframe/resources/window-bar/fullscreen.svg b/src/shared/resources/window-bar/fullscreen.svg similarity index 100% rename from src/shared/widgetframe/resources/window-bar/fullscreen.svg rename to src/shared/resources/window-bar/fullscreen.svg diff --git a/src/shared/widgetframe/resources/window-bar/maximize.svg b/src/shared/resources/window-bar/maximize.svg similarity index 100% rename from src/shared/widgetframe/resources/window-bar/maximize.svg rename to src/shared/resources/window-bar/maximize.svg diff --git a/src/shared/widgetframe/resources/window-bar/minimize.svg b/src/shared/resources/window-bar/minimize.svg similarity index 100% rename from src/shared/widgetframe/resources/window-bar/minimize.svg rename to src/shared/resources/window-bar/minimize.svg diff --git a/src/shared/widgetframe/resources/window-bar/more-line.svg b/src/shared/resources/window-bar/more-line.svg similarity index 100% rename from src/shared/widgetframe/resources/window-bar/more-line.svg rename to src/shared/resources/window-bar/more-line.svg diff --git a/src/shared/widgetframe/resources/window-bar/restore.svg b/src/shared/resources/window-bar/restore.svg similarity index 100% rename from src/shared/widgetframe/resources/window-bar/restore.svg rename to src/shared/resources/window-bar/restore.svg diff --git a/src/shared/widgetframe/CMakeLists.txt b/src/shared/widgetframe/CMakeLists.txt index 7ccfec3..bf43085 100644 --- a/src/shared/widgetframe/CMakeLists.txt +++ b/src/shared/widgetframe/CMakeLists.txt @@ -6,13 +6,14 @@ set(CMAKE_AUTORCC ON) file(GLOB _src *.h *.cpp) -add_library(${PROJECT_NAME} STATIC "") +qt_add_library(${PROJECT_NAME} STATIC "") target_sources(${PROJECT_NAME} PRIVATE windowbar.cpp windowbutton.cpp PUBLIC + windowbar.h windowbar_p.h windowbutton.h windowbutton_p.h @@ -20,7 +21,7 @@ PUBLIC qt6_add_resources(${PROJECT_NAME} "resources" PREFIX "/" - FILES "resources/shared.qrc" + FILES "../resources/shared.qrc" ) target_link_libraries(${PROJECT_NAME} PRIVATE diff --git a/src/shared/widgetframe/windowbar.cpp b/src/shared/widgetframe/windowbar.cpp index 362383f..38a398e 100644 --- a/src/shared/widgetframe/windowbar.cpp +++ b/src/shared/widgetframe/windowbar.cpp @@ -79,14 +79,19 @@ namespace QWK { return static_cast(d->widgetAt(WindowBarPrivate::IconButton)); } + QAbstractButton *WindowBar::pinButton() const { + Q_D(const WindowBar); + return static_cast(d->widgetAt(WindowBarPrivate::PinButton)); + } + QAbstractButton *WindowBar::minButton() const { Q_D(const WindowBar); - return static_cast(d->widgetAt(WindowBarPrivate::MinimumButton)); + return static_cast(d->widgetAt(WindowBarPrivate::MinimizeButton)); } QAbstractButton *WindowBar::maxButton() const { Q_D(const WindowBar); - return static_cast(d->widgetAt(WindowBarPrivate::MaximumButton)); + return static_cast(d->widgetAt(WindowBarPrivate::MaximizeButton)); } QAbstractButton *WindowBar::closeButton() const { @@ -131,6 +136,17 @@ namespace QWK { btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); } + void WindowBar::setPinButton(QAbstractButton *btn) { + Q_D(WindowBar); + auto org = takePinButton(); + if (org) + org->deleteLater(); + if (!btn) + return; + d->setWidgetAt(WindowBarPrivate::PinButton, btn); + connect(btn, &QAbstractButton::clicked, this, &WindowBar::pinRequested); + } + void WindowBar::setMinButton(QAbstractButton *btn) { Q_D(WindowBar); auto org = takeMinButton(); @@ -138,7 +154,7 @@ namespace QWK { org->deleteLater(); if (!btn) return; - d->setWidgetAt(WindowBarPrivate::MinimumButton, btn); + d->setWidgetAt(WindowBarPrivate::MinimizeButton, btn); connect(btn, &QAbstractButton::clicked, this, &WindowBar::minimizeRequested); } @@ -149,7 +165,7 @@ namespace QWK { org->deleteLater(); if (!btn) return; - d->setWidgetAt(WindowBarPrivate::MaximumButton, btn); + d->setWidgetAt(WindowBarPrivate::MaximizeButton, btn); connect(btn, &QAbstractButton::clicked, this, &WindowBar::maximizeRequested); } @@ -179,9 +195,19 @@ namespace QWK { return static_cast(d->takeWidgetAt(WindowBarPrivate::IconButton)); } + QAbstractButton *WindowBar::takePinButton() { + Q_D(WindowBar); + auto btn = static_cast(d->takeWidgetAt(WindowBarPrivate::PinButton)); + if (!btn) { + return nullptr; + } + disconnect(btn, &QAbstractButton::clicked, this, &WindowBar::pinRequested); + return btn; + } + QAbstractButton *WindowBar::takeMinButton() { Q_D(WindowBar); - auto btn = static_cast(d->takeWidgetAt(WindowBarPrivate::MinimumButton)); + auto btn = static_cast(d->takeWidgetAt(WindowBarPrivate::MinimizeButton)); if (!btn) { return nullptr; } @@ -191,7 +217,7 @@ namespace QWK { QAbstractButton *WindowBar::takeMaxButton() { Q_D(WindowBar); - auto btn = static_cast(d->takeWidgetAt(WindowBarPrivate::MaximumButton)); + auto btn = static_cast(d->takeWidgetAt(WindowBarPrivate::MaximizeButton)); if (!btn) { return nullptr; } diff --git a/src/shared/widgetframe/windowbar.h b/src/shared/widgetframe/windowbar.h index 2e802f2..e9cf04c 100644 --- a/src/shared/widgetframe/windowbar.h +++ b/src/shared/widgetframe/windowbar.h @@ -25,6 +25,7 @@ namespace QWK { QMenuBar *menuBar() const; QLabel *titleLabel() const; QAbstractButton *iconButton() const; + QAbstractButton *pinButton() const; QAbstractButton *minButton() const; QAbstractButton *maxButton() const; QAbstractButton *closeButton() const; @@ -32,6 +33,7 @@ namespace QWK { void setMenuBar(QMenuBar *menuBar); void setTitleLabel(QLabel *label); void setIconButton(QAbstractButton *btn); + void setPinButton(QAbstractButton *btn); void setMinButton(QAbstractButton *btn); void setMaxButton(QAbstractButton *btn); void setCloseButton(QAbstractButton *btn); @@ -39,6 +41,7 @@ namespace QWK { QMenuBar *takeMenuBar(); QLabel *takeTitleLabel(); QAbstractButton *takeIconButton(); + QAbstractButton *takePinButton(); QAbstractButton *takeMinButton(); QAbstractButton *takeMaxButton(); QAbstractButton *takeCloseButton(); @@ -53,6 +56,7 @@ namespace QWK { void setIconFollowWindow(bool value); Q_SIGNALS: + void pinRequested(bool pin = false); void minimizeRequested(); void maximizeRequested(bool max = false); void closeRequested(); diff --git a/src/shared/widgetframe/windowbar_p.h b/src/shared/widgetframe/windowbar_p.h index 36ceb17..35422ae 100644 --- a/src/shared/widgetframe/windowbar_p.h +++ b/src/shared/widgetframe/windowbar_p.h @@ -29,8 +29,9 @@ namespace QWK { IconButton, MenuWidget, TitleLabel, - MinimumButton, - MaximumButton, + PinButton, + MinimizeButton, + MaximizeButton, CloseButton, };