examples/CMakeLists.txt
@@ -13,6 +13,10 @@ add_subdirectory(shared) add_subdirectory(mainwindow) if(QWINDOWKIT_BUILD_WIDGETS) add_subdirectory(mainwindow) endif() add_subdirectory(qml) if(QWINDOWKIT_BUILD_QUICK) add_subdirectory(qml) endif() examples/mainwindow/CMakeLists.txt
@@ -3,7 +3,12 @@ file(GLOB _src *.h *.cpp) qwk_add_example(${PROJECT_NAME} SOURCES ${_src} SOURCES ${_src} mainwindow.qrc ../shared/resources/window-bar.qrc QT_LINKS Core Gui Widgets LINKS QWKWidgets WidgetFrame ) ) set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED TRUE ) examples/mainwindow/dark-style.qss
New file @@ -0,0 +1,153 @@ /* Window bar */ QWK--WindowBar[bar-active=true] { background-color: #3C3C3C; } QWK--WindowBar[bar-active=false] { background-color: #505050; } /* Title label */ QWK--WindowBar>QLabel#win-title-label { padding: 0; border: none; color: #ECECEC; background-color: transparent; } /* System buttons */ QWK--WindowBar>QAbstractButton[system-button=true] { qproperty-iconSize: 12px 12px; min-width: 50px; border: none; padding: 0; background-color: transparent; } QWK--WindowBar>QAbstractButton#min-button { qproperty-iconNormal: url(":/window-bar/minimize.svg"); qproperty-iconSize: 12px 12px; } QWK--WindowBar>QAbstractButton#min-button:hover, QWK--WindowBar>QAbstractButton#min-button:pressed { background-color: rgba(0, 0, 0, 15%); } QWK--WindowBar>QAbstractButton#max-button { qproperty-iconNormal: url(":/window-bar/maximize.svg"); qproperty-iconChecked: url(":/window-bar/restore.svg"); } QWK--WindowBar>QAbstractButton#max-button:hover, QWK--WindowBar>QAbstractButton#max-button:pressed { background-color: rgba(0, 0, 0, 15%); } QWK--WindowBar>QAbstractButton#close-button { qproperty-iconNormal: url(":/window-bar/close.svg"); } QWK--WindowBar>QAbstractButton#close-button:hover, QWK--WindowBar>QAbstractButton#close-button:pressed { background-color: #e81123; } /* Icon button */ QWK--WindowBar>QAbstractButton#icon-button { qproperty-iconNormal: url(":/window-bar/icon.svg"); qproperty-iconSize: 20px 20px; min-width: 40px; border: none; padding: 0; background-color: transparent; } /* Menu Bar */ QMenuBar { background-color: transparent; border: none; } QMenuBar>QToolButton#qt_menubar_ext_button { qproperty-icon: url(":/window-bar/more-line.svg"); } QMenuBar>QToolButton#qt_menubar_ext_button:hover, QMenuBar>QToolButton#qt_menubar_ext_button:pressed { background-color: rgba(255, 255, 255, 10%); } QMenuBar::item { color: #CCCCCC; border: none; padding: 8px 12px; } QMenuBar::item:selected { background-color: rgba(255, 255, 255, 10%); } /* Menu */ QMenu { padding: 4px; background: #303030; border: 1.25px solid transparent; } QMenu::indicator { left: 6px; width: 20px; height: 20px; } QMenu::icon { left: 6px; } QMenu::item { background: transparent; color: #CCCCCC; padding: 6px 24px; } QMenu::item:selected { color: white; background-color: #0060C0; } QMenu::item:disabled { color: #666666; background-color: transparent; } QMenu::separator { height: 2px; background-color: #5B5B5B; margin: 6px 0; } /* Window */ MainWindow { background-color: #1E1E1E; } QWidget#clock-widget { font-size: 75px; color: #FEFEFE; font-weight: bold; background-color: transparent; } examples/mainwindow/main.cpp
@@ -1,4 +1,5 @@ #include <QtWidgets/QApplication> #include <QtGui/QFont> #include <QtCore/QDebug> #include "mainwindow.h" @@ -17,6 +18,15 @@ QGuiApplication::setHighDpiScaleFactorRoundingPolicy( Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); QApplication a(argc, argv); #ifdef Q_OS_WINDOWS a.setFont([]() { QFont f("Microsoft YaHei"); f.setPixelSize(15); return f; }()); #endif MainWindow w; w.show(); return a.exec(); examples/mainwindow/mainwindow.cpp
@@ -1,17 +1,23 @@ #include "mainwindow.h" #include <QtCore/QDebug> #include <QtCore/QFile> #include <QtCore/QTime> #include <QtCore/QTimer> #include <QtWidgets/QApplication> #include <QtWidgets/QStyle> #include <QtWidgets/QPushButton> #include <QWKWidgets/widgetwindowagent.h> #include <widgetframe/windowbar.h> #include <widgetframe/windowbutton.h> class ClockWidget : public QPushButton { class ClockWidget : public QLabel { public: explicit ClockWidget(QWidget *parent = nullptr) : QPushButton(parent) { explicit ClockWidget(QWidget *parent = nullptr) : QLabel(parent) { startTimer(100); setAlignment(Qt::AlignCenter); } ~ClockWidget() override = default; @@ -24,9 +30,79 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { installWindowAgent(); auto clockWidget = new ClockWidget(); clockWidget->setObjectName("clock-widget"); clockWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setCentralWidget(clockWidget); if (QFile qss(":/dark-style.qss"); qss.open(QIODevice::ReadOnly | QIODevice::Text)) { setStyleSheet(QString::fromUtf8(qss.readAll())); } setWindowTitle("Example MainWindow"); resize(640, 480); } static inline void emulateLeaveEvent(QWidget *widget) { Q_ASSERT(widget); if (!widget) { return; } QTimer::singleShot(0, widget, [widget]() { #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) const QScreen *screen = widget->screen(); #else const QScreen *screen = widget->windowHandle()->screen(); #endif const QPoint globalPos = QCursor::pos(screen); if (!QRect(widget->mapToGlobal(QPoint{0, 0}), widget->size()).contains(globalPos)) { QCoreApplication::postEvent(widget, new QEvent(QEvent::Leave)); if (widget->testAttribute(Qt::WA_Hover)) { const QPoint localPos = widget->mapFromGlobal(globalPos); const QPoint scenePos = widget->window()->mapFromGlobal(globalPos); static constexpr const auto oldPos = QPoint{}; const Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); #if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)) const auto event = new QHoverEvent(QEvent::HoverLeave, scenePos, globalPos, oldPos, modifiers); Q_UNUSED(localPos); #elif (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)) const auto event = new QHoverEvent(QEvent::HoverLeave, localPos, globalPos, oldPos, modifiers); Q_UNUSED(scenePos); #else const auto event = new QHoverEvent(QEvent::HoverLeave, localPos, oldPos, modifiers); Q_UNUSED(scenePos); #endif QCoreApplication::postEvent(widget, event); } } }); } MainWindow::~MainWindow() { } bool MainWindow::event(QEvent *event) { switch (event->type()) { case QEvent::WindowActivate: { auto menu = menuWidget(); menu->setProperty("bar-active", true); style()->polish(menu); break; } case QEvent::WindowDeactivate: { auto menu = menuWidget(); menu->setProperty("bar-active", false); style()->polish(menu); break; } default: break; } return QMainWindow::event(event); } void MainWindow::installWindowAgent() { @@ -35,37 +111,45 @@ qFatal("Frameless handle failed to initialize."); } auto titleLabel = new QLabel(); titleLabel->setAlignment(Qt::AlignCenter); auto menuBar = []() { auto menuBar = new QMenuBar(); auto file = new QMenu("File(&F)"); file->addAction(new QAction("New(&N)")); file->addAction(new QAction("Open(&O)")); auto file = new QMenu("File(&F)", menuBar); file->addAction(new QAction("New(&N)", menuBar)); file->addAction(new QAction("Open(&O)", menuBar)); auto edit = new QMenu("Edit(&E)"); edit->addAction(new QAction("Undo(&U)")); edit->addAction(new QAction("Redo(&R)")); auto edit = new QMenu("Edit(&E)", menuBar); edit->addAction(new QAction("Undo(&U)", menuBar)); edit->addAction(new QAction("Redo(&R)", menuBar)); menuBar->addMenu(file); menuBar->addMenu(edit); return menuBar; }(); menuBar->setObjectName("win-menu-bar"); auto iconButton = new QPushButton("I"); iconButton->setAttribute(Qt::WA_Hover); iconButton->setMouseTracking(true); auto minButton = new QPushButton("—"); minButton->setAttribute(Qt::WA_Hover); minButton->setMouseTracking(true); auto maxButton = new QPushButton("🗖"); auto titleLabel = new QLabel(); titleLabel->setAlignment(Qt::AlignCenter); titleLabel->setObjectName("win-title-label"); auto iconButton = new QWK::WindowButton(); iconButton->setObjectName("icon-button"); iconButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); auto minButton = new QWK::WindowButton(); minButton->setObjectName("min-button"); minButton->setProperty("system-button", true); minButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); auto maxButton = new QWK::WindowButton(); maxButton->setCheckable(true); maxButton->setAttribute(Qt::WA_Hover); maxButton->setMouseTracking(true); auto closeButton = new QPushButton("✖"); closeButton->setAttribute(Qt::WA_Hover); closeButton->setMouseTracking(true); maxButton->setObjectName("max-button"); maxButton->setProperty("system-button", true); maxButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); auto closeButton = new QWK::WindowButton(); closeButton->setObjectName("close-button"); closeButton->setProperty("system-button", true); closeButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); auto windowBar = new QWK::WindowBar(); windowBar->setIconButton(iconButton); @@ -83,29 +167,37 @@ agent->setSystemButton(QWK::WindowAgentBase::Close, closeButton); agent->setHitTestVisible(menuBar, true); #ifdef Q_OS_WINDOWS // Emulate Window system menu button behaviors connect(iconButton, &QAbstractButton::clicked, agent, [this, iconButton, agent] { setProperty("double-click-close", false); // Pick a suitable time threshold QTimer::singleShot(75, this, [this, iconButton, agent]() { if (property("double-click-close").toBool()) return; agent->showSystemMenu(iconButton->mapToGlobal({0, iconButton->height()})); }); }); connect(iconButton, &QWK::WindowButton::doubleClicked, this, [this]() { setProperty("double-click-close", true); close(); }); #endif connect(windowBar, &QWK::WindowBar::minimizeRequested, this, &QWidget::showMinimized); connect(windowBar, &QWK::WindowBar::maximizeRequested, this, [this](bool max) { 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 // manully send leave events to the button. emulateLeaveEvent(maxButton); }); connect(windowBar, &QWK::WindowBar::closeRequested, this, &QWidget::close); auto clockWidget = new ClockWidget(); clockWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); connect(clockWidget, &QAbstractButton::clicked, this, [this]() { if (!isMaximized()) { showMaximized(); } else { showNormal(); } }); setMenuWidget(windowBar); setCentralWidget(clockWidget); setWindowTitle("Example MainWindow"); // setContentsMargins({0, 1, 0, 0}); resize(640, 480); } examples/mainwindow/mainwindow.h
@@ -4,11 +4,15 @@ #include <QtWidgets/QMainWindow> class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); ~MainWindow() override; protected: bool event(QEvent *event) override; private: void installWindowAgent(); }; examples/mainwindow/mainwindow.qrc
New file @@ -0,0 +1,5 @@ <RCC> <qresource prefix="/"> <file>dark-style.qss</file> </qresource> </RCC> examples/qml/CMakeLists.txt
@@ -6,4 +6,9 @@ SOURCES ${_src} QT_LINKS Core Gui Qml Quick LINKS QWKQuick ) ) set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED TRUE ) examples/shared/resources/window-bar.qrc
New file @@ -0,0 +1,11 @@ <RCC> <qresource prefix="/"> <file>window-bar/close.svg</file> <file>window-bar/fullscreen.svg</file> <file>window-bar/icon.svg</file> <file>window-bar/maximize.svg</file> <file>window-bar/minimize.svg</file> <file>window-bar/restore.svg</file> <file>window-bar/more-line.svg</file> </qresource> </RCC> examples/shared/resources/window-bar/close.svg
New file @@ -0,0 +1,15 @@ <svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" width="10.88" height="10.88" viewBox="0 0 10.88 10.88"> <defs> <style> .cls-1 { fill: none; stroke: white; stroke-miterlimit: 10; stroke-width: 1.25px; } </style> </defs> <line class="cls-1" x1="0.44" y1="0.44" x2="10.44" y2="10.44" /> <line class="cls-1" x1="0.44" y1="10.44" x2="10.44" y2="0.44" /> </svg> examples/shared/resources/window-bar/fullscreen.svg
New file @@ -0,0 +1,11 @@ <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1594017175519" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1933" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"> <defs> <style type="text/css"></style> </defs> <path d="M874.666667 128h-170.666667a21.333333 21.333333 0 0 0 0 42.666667h119.168l-176.917333 176.917333a21.333333 21.333333 0 1 0 30.165333 30.165333L853.333333 200.832V320a21.333333 21.333333 0 0 0 42.666667 0V149.333333a21.333333 21.333333 0 0 0-21.333333-21.333333zM347.584 646.250667L170.666667 823.168V704a21.333333 21.333333 0 0 0-42.666667 0v170.666667a21.333333 21.333333 0 0 0 21.333333 21.333333h170.666667a21.333333 21.333333 0 0 0 0-42.666667H200.832l176.917333-176.917333a21.333333 21.333333 0 0 0-30.165333-30.165333zM874.666667 682.666667a21.333333 21.333333 0 0 0-21.333334 21.333333v119.168l-176.917333-176.917333a21.333333 21.333333 0 0 0-30.165333 30.165333L823.168 853.333333H704a21.333333 21.333333 0 0 0 0 42.666667h170.666667a21.333333 21.333333 0 0 0 21.333333-21.333333v-170.666667a21.333333 21.333333 0 0 0-21.333333-21.333333zM200.832 170.666667H320a21.333333 21.333333 0 0 0 0-42.666667H149.333333a21.333333 21.333333 0 0 0-21.333333 21.333333v170.666667a21.333333 21.333333 0 0 0 42.666667 0V200.832l176.917333 176.917333a21.333333 21.333333 0 0 0 30.165333-30.165333z" fill="#ffffff" p-id="1934"></path> </svg> examples/shared/resources/window-bar/icon.svg
New file @@ -0,0 +1,18 @@ <?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1597412561411" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="780" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"> <defs> <style type="text/css"></style> </defs> <path d="M512 384m-170.666667 0a170.666667 170.666667 0 1 0 341.333334 0 170.666667 170.666667 0 1 0-341.333334 0Z" fill="#009688" p-id="781"></path> <path d="M341.333333 384h341.333334v128H341.333333z" fill="#E89419" p-id="782"></path> <path d="M661.333333 106.666667v85.333333h-46.933333c-51.2 0-25.6-21.333333-102.4-21.333333V85.333333c76.8 0 51.2 21.333333 102.4 21.333334H661.333333z" fill="#2196F3" p-id="783"></path> <path d="M85.333333 512h853.333334v362.666667H85.333333z" fill="#FFB74D" p-id="784"></path> <path d="M661.333333 725.333333h85.333334v106.666667h-85.333334zM533.333333 725.333333h85.333334v106.666667h-85.333334zM405.333333 725.333333h85.333334v106.666667h-85.333334zM789.333333 725.333333h85.333334v106.666667h-85.333334zM277.333333 725.333333h85.333334v106.666667h-85.333334zM149.333333 725.333333h85.333334v106.666667H149.333333zM661.333333 576h85.333334v106.666667h-85.333334zM533.333333 576h85.333334v106.666667h-85.333334zM405.333333 576h85.333334v106.666667h-85.333334zM618.666667 512h-85.333334v-64c0-23.466667 19.2-42.666667 42.666667-42.666667s42.666667 19.2 42.666667 42.666667v64zM490.666667 512h-85.333334v-64c0-23.466667 19.2-42.666667 42.666667-42.666667s42.666667 19.2 42.666667 42.666667v64zM789.333333 576h85.333334v106.666667h-85.333334zM277.333333 576h85.333334v106.666667h-85.333334zM149.333333 576h85.333334v106.666667H149.333333z" fill="#B07424" p-id="785"></path> </svg> examples/shared/resources/window-bar/maximize.svg
New file @@ -0,0 +1,12 @@ <svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 10 10"> <defs> <style> .cls-1 { fill: none; stroke: white; stroke-miterlimit: 10; } </style> </defs> <rect class="cls-1" x="0.5" y="0.5" width="9" height="9" /> </svg> examples/shared/resources/window-bar/minimize.svg
New file @@ -0,0 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 10 10" style="enable-background:new 0 0 10 10;" xml:space="preserve"> <style type="text/css"> .st0 { fill: white; } </style> <rect y="4.5" class="st0" width="10" height="1" /> </svg> examples/shared/resources/window-bar/more-line.svg
New file @@ -0,0 +1,5 @@ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"> <path fill="none" d="M0 0h24v24H0z" /> <path fill="white" d="M4.5 10.5c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5S6 12.825 6 12s-.675-1.5-1.5-1.5zm15 0c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5S21 12.825 21 12s-.675-1.5-1.5-1.5zm-7.5 0c-.825 0-1.5.675-1.5 1.5s.675 1.5 1.5 1.5 1.5-.675 1.5-1.5-.675-1.5-1.5-1.5z" /> </svg> examples/shared/resources/window-bar/restore.svg
New file @@ -0,0 +1,16 @@ <svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12"> <defs> <style> .cls-1 { fill: none; stroke: white; stroke-miterlimit: 10; } </style> </defs> <rect class="cls-1" x="0.5" y="2.5" width="9" height="9" /> <line class="cls-1" x1="2.5" y1="2.5" x2="2.5" y2="0.5" /> <line class="cls-1" x1="12" y1="0.5" x2="2" y2="0.5" /> <line class="cls-1" x1="11.5" y1="10" x2="11.5" /> <line class="cls-1" x1="10" y1="9.5" x2="12" y2="9.5" /> </svg> examples/shared/widgetframe/CMakeLists.txt
@@ -13,4 +13,9 @@ QT_LINKS Core Gui Widgets ) set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED TRUE ) target_include_directories(${PROJECT_NAME} PUBLIC . ..) examples/shared/widgetframe/windowbutton.cpp
New file @@ -0,0 +1,92 @@ #include "windowbutton.h" #include "windowbutton_p.h" #include <QtCore/QDebug> #include <QtGui/QtEvents> namespace QWK { WindowButtonPrivate::WindowButtonPrivate() { } WindowButtonPrivate::~WindowButtonPrivate() { } void WindowButtonPrivate::init() { } void WindowButtonPrivate::reloadIcon() { Q_Q(WindowButton); if (!q->isEnabled() && !iconDisabled.isNull()) { q->setIcon(iconDisabled); return; } if (q->isChecked() && !iconChecked.isNull()) { q->setIcon(iconChecked); return; } if (!iconNormal.isNull()) { q->setIcon(iconNormal); } } WindowButton::WindowButton(QWidget *parent) : WindowButton(*new WindowButtonPrivate(), parent) { } WindowButton::~WindowButton() = default; QIcon WindowButton::iconNormal() const { Q_D(const WindowButton); return d->iconNormal; } void WindowButton::setIconNormal(const QIcon &icon) { Q_D(WindowButton); d->iconNormal = icon; d->reloadIcon(); } QIcon WindowButton::iconChecked() const { Q_D(const WindowButton); return d->iconChecked; } void WindowButton::setIconChecked(const QIcon &icon) { Q_D(WindowButton); d->iconChecked = icon; d->reloadIcon(); } QIcon WindowButton::iconDisabled() const { Q_D(const WindowButton); return d->iconDisabled; } void WindowButton::setIconDisabled(const QIcon &icon) { Q_D(WindowButton); d->iconDisabled = icon; d->reloadIcon(); } void WindowButton::checkStateSet() { Q_D(WindowButton); d->reloadIcon(); } void WindowButton::mouseDoubleClickEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { Q_EMIT doubleClicked(); } } WindowButton::WindowButton(WindowButtonPrivate &d, QWidget *parent) : QPushButton(parent), d_ptr(&d) { d.q_ptr = this; d.init(); } } examples/shared/widgetframe/windowbutton.h
New file @@ -0,0 +1,48 @@ #ifndef WINDOWBUTTON_H #define WINDOWBUTTON_H #include "QPushButton.h" #include <QtGlobal> namespace QWK { class WindowButtonPrivate; class WindowButton : public QPushButton { Q_OBJECT Q_DECLARE_PRIVATE(WindowButton) Q_PROPERTY(QIcon iconNormal READ iconNormal WRITE setIconNormal FINAL) Q_PROPERTY(QIcon iconChecked READ iconChecked WRITE setIconChecked FINAL) Q_PROPERTY(QIcon iconDisabled READ iconDisabled WRITE setIconDisabled FINAL) public: explicit WindowButton(QWidget *parent = nullptr); ~WindowButton(); public: QIcon iconNormal() const; void setIconNormal(const QIcon &icon); QIcon iconChecked() const; void setIconChecked(const QIcon &icon); QIcon iconDisabled() const; void setIconDisabled(const QIcon &icon); Q_SIGNALS: void doubleClicked(); protected: void checkStateSet() override; void mouseDoubleClickEvent(QMouseEvent *event) override; protected: WindowButton(WindowButtonPrivate &d, QWidget *parent = nullptr); QScopedPointer<WindowButtonPrivate> d_ptr; }; } #endif // WINDOWBUTTON_H examples/shared/widgetframe/windowbutton_p.h
New file @@ -0,0 +1,27 @@ #ifndef WINDOWBUTTONPRIVATE_H #define WINDOWBUTTONPRIVATE_H #include "windowbutton.h" namespace QWK { class WindowButtonPrivate { Q_DECLARE_PUBLIC(WindowButton) public: WindowButtonPrivate(); virtual ~WindowButtonPrivate(); void init(); WindowButton *q_ptr; QIcon iconNormal; QIcon iconChecked; QIcon iconDisabled; void reloadIcon(); }; } #endif // WINDOWBUTTONPRIVATE_H src/core/contexts/abstractwindowcontext.cpp
@@ -195,6 +195,7 @@ map.insert(QStringLiteral("inactiveDark"), kSampleColorSet.inactiveDark); return; } default: break; } src/core/contexts/win32windowcontext.cpp
@@ -849,6 +849,7 @@ QPoint{m_windowHandle->width(), 0} }); painter.restore(); return; } default: { src/widgets/widgetwindowagent_win.cpp
@@ -81,7 +81,7 @@ ®ion, }; ctx->virtual_hook(AbstractWindowContext::DrawWindows10BorderHook, args); return true; break; } case QEvent::WindowStateChange: {