diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e10d36..7eff6fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,8 @@ set(CMAKE_AUTORCC ON) find_package(QT NAMES Qt6 Qt5 COMPONENTS Gui REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Gui REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets) find_package(QT NAMES Qt6 Qt5 COMPONENTS Quick) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Quick) diff --git a/examples/minimal/flwindow.cpp b/examples/minimal/flwindow.cpp index 7d1c997..c1b4906 100644 --- a/examples/minimal/flwindow.cpp +++ b/examples/minimal/flwindow.cpp @@ -8,7 +8,7 @@ FRAMELESSHELPER_USE_NAMESPACE -FLWindow::FLWindow(QWidget *parent) : QWidget(parent) +FLWindow::FLWindow(QWidget *parent) : FramelessWindow(parent) { setWindowFlags(Qt::FramelessWindowHint); setupUi(); @@ -21,52 +21,6 @@ FLWindow::~FLWindow() } -void FLWindow::initFramelessWindow() -{ - m_helper = new FramelessHelper(windowHandle()); - m_helper->setResizeBorderThickness(4); - m_helper->setTitleBarHeight(m_titleBarWidget->height()); - m_helper->setResizable(true); - m_helper->setHitTestVisible(m_minimizeButton); - m_helper->setHitTestVisible(m_maximizeButton); - m_helper->setHitTestVisible(m_closeButton); - m_helper->install(); - -#ifdef Q_OS_MAC - m_minimizeButton->hide(); - m_maximizeButton->hide(); - m_closeButton->hide(); - Utilities::setStandardWindowButtonsVisibility(windowHandle(), true); - auto btnGroupSize = Utilities::standardWindowButtonsSize(windowHandle()); - Utilities::setStandardWindowButtonsPosition(windowHandle(), - QPoint(12, (m_titleBarWidget->height() - btnGroupSize.height())/2)); -#endif -} - -void FLWindow::showEvent(QShowEvent *event) -{ - QWidget::showEvent(event); - - static bool inited = false; - if (!inited) { - inited = true; - initFramelessWindow(); - } -} - -#ifdef Q_OS_WIN -bool FLWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) -{ - if (!m_helper) - return QWidget::nativeEvent(eventType, message, result); - - if (m_helper->handleNativeEvent(this->windowHandle(), eventType, message, result)) - return true; - else - return QWidget::nativeEvent(eventType, message, result); -} -#endif // Q_OS_WIN - void FLWindow::setupUi() { resize(800, 600); @@ -113,4 +67,11 @@ void FLWindow::setupUi() mainLayout->addWidget(m_titleBarWidget); mainLayout->addStretch(); setLayout(mainLayout); + + setResizeBorderThickness(4); + setTitleBarHeight(m_titleBarWidget->height()); + setResizable(true); + setHitTestVisible(m_minimizeButton); + setHitTestVisible(m_maximizeButton); + setHitTestVisible(m_closeButton); } diff --git a/examples/minimal/flwindow.h b/examples/minimal/flwindow.h index 2fbb5ed..b00b5d9 100644 --- a/examples/minimal/flwindow.h +++ b/examples/minimal/flwindow.h @@ -1,29 +1,21 @@ #pragma once #include -#include "core/framelesshelper.h" +#include "widget/framelesswindow.h" class QPushButton; -class FLWindow : public QWidget +class FLWindow : public __flh_ns::FramelessWindow { Q_OBJECT public: explicit FLWindow(QWidget *parent = nullptr); - ~FLWindow(); - -protected: - void showEvent(QShowEvent *event) override; -#ifdef Q_OS_WIN - bool nativeEvent(const QByteArray &eventType, void *message, long *result) override; -#endif // Q_OS_WIN + ~FLWindow() override; private: - void initFramelessWindow(); void setupUi(); private: - __flh_ns::FramelessHelper *m_helper = nullptr; QWidget *m_titleBarWidget = nullptr; QPushButton *m_minimizeButton = nullptr; QPushButton *m_maximizeButton = nullptr; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2ac9f2d..dd044e6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,13 @@ set(SOURCES core/framelesswindowsmanager.cpp ) + +if(TARGET Qt${QT_VERSION_MAJOR}::Widgets) + list(APPEND SOURCES + widget/framelesswindow.h + ) +endif() + if(TARGET Qt${QT_VERSION_MAJOR}::Quick) list(APPEND SOURCES quick/framelessquickhelper.h @@ -94,6 +101,12 @@ if(TARGET Qt${QT_VERSION_MAJOR}::Quick) ) endif() +if(TARGET Qt${QT_VERSION_MAJOR}::Widgets) + target_link_libraries(${PROJECT_NAME} PRIVATE + Qt${QT_VERSION_MAJOR}::WidgetsPrivate + ) +endif() + target_include_directories(${PROJECT_NAME} PUBLIC "$" ) diff --git a/src/widget/framelesswindow.h b/src/widget/framelesswindow.h new file mode 100644 index 0000000..998b8ab --- /dev/null +++ b/src/widget/framelesswindow.h @@ -0,0 +1,76 @@ +#pragma once + +#include + +#include "core/framelesshelper.h" + +FRAMELESSHELPER_BEGIN_NAMESPACE + +template +class FramelessWindow : public T +{ + static_assert(std::is_base_of::value, "T must inherit from QWidget"); + +public: + explicit FramelessWindow(QWidget *parent = nullptr) + : T(parent), m_helper(new FramelessHelper) {} + + ~FramelessWindow() { + delete m_helper; + } + + FramelessHelper *helper() { return m_helper; } + + void setResizable(bool reziable) + { + m_helper->setResizable(reziable); + } + + void setHitTestVisible(QObject *obj) + { + m_helper->setHitTestVisible(obj); + } + + void setResizeBorderThickness(int thickness) { + m_helper->setResizeBorderThickness(thickness); + } + + void setTitleBarHeight(int height) + { + m_helper->setTitleBarHeight(height); + } + +protected: + void showEvent(QShowEvent *event) override + { + T::showEvent(event); + + if (!m_initied) { + const auto win = this->windowHandle(); + if (win) { + m_helper->setWindow(win); + m_helper->install(); + m_initied = true; + } + } + } + +#ifdef Q_OS_WIN + bool nativeEvent(const QByteArray &eventType, void *message, long *result) override + { + if (!m_helper) + return T::nativeEvent(eventType, message, result); + + if (m_helper->handleNativeEvent(this->windowHandle(), eventType, message, result)) + return true; + else + return T::nativeEvent(eventType, message, result); + } +#endif // Q_OS_WIN + +private: + FramelessHelper *m_helper; + bool m_initied = false; +}; + +FRAMELESSHELPER_END_NAMESPACE