add window icon support

Signed-off-by: Yuhang Zhao <2546789017@qq.com>
This commit is contained in:
Yuhang Zhao 2022-08-29 17:50:30 +08:00
parent e55afa2fe3
commit 463ac0a999
27 changed files with 646 additions and 28 deletions

View File

@ -17,10 +17,14 @@ You can join our [Discord channel](https://discord.gg/grrM4Tmesy) to communicate
## Highlights v2.2 ## Highlights v2.2
- Common: Added blur behind window feature for Windows (7~11), Linux and macOS. - Common: Added blur behind window feature for Windows (7~11), Linux and macOS. On Windows 11 and macOS, FramelessHelper will make use of the blur effect provided by the OS to get the best appearance and performance, while on Windows 7~10 and Linux, FramelessHelper will use a homemade blur effect to provide as much consistent experience as possible.
- CMake: Implemented CMake package support. It's now possible to use `find_package` to find FramelessHelper. - Common: Added window icon support. It's now possible to set the window icon's image, size and visibility for the standard title bar control.
- Windows: If you are using Qt 6.4+, your Qt Widgets applications will now automatically switch to light/dark theme if the OS theme changes. It requires you are using the default palette provided by Qt. Qt Quick applications will not be affected.
- Linux: FramelessHelper is now theme-aware. If you change your OS theme, FramelessHelper will now emit the theme change signal and refresh it's internal palette.
- Build system: Implemented CMake package support. It's now possible to use `find_package` to find FramelessHelper.
- Build system: Implemented limited QMake support. FramelessHelper doesn't provide complete QMake project, to decrease the maintainance burden, but you can use the .pri files to directly embed FramelessHelper into your own application.
- Examples: Enabled blur behind window and round window corner by default. - Examples: Enabled blur behind window and round window corner by default.
- Common: Migrated to categorized logging output. - Common: Migrated to categorized logging output. You can now enable or disable some specific debug messages using QLoggingCategory.
- Common: Internal code improvements & bug fixes. - Common: Internal code improvements & bug fixes.
## Highlights v2.1 ## Highlights v2.1

View File

@ -29,6 +29,7 @@
#include <QtCore/qfileinfo.h> #include <QtCore/qfileinfo.h>
#include <QtCore/qdir.h> #include <QtCore/qdir.h>
#include <QtWidgets/qboxlayout.h> #include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qfileiconprovider.h>
#include <Utils> #include <Utils>
#include <StandardTitleBar> #include <StandardTitleBar>
#include <StandardSystemButton> #include <StandardSystemButton>
@ -118,4 +119,5 @@ QMenuBar::item:pressed {
}); });
setWindowTitle(tr("FramelessHelper demo application - Qt MainWindow")); setWindowTitle(tr("FramelessHelper demo application - Qt MainWindow"));
setWindowIcon(QFileIconProvider().icon(QFileIconProvider::Computer));
} }

View File

@ -29,6 +29,7 @@
#include <QtCore/qfileinfo.h> #include <QtCore/qfileinfo.h>
#include <QtCore/qdir.h> #include <QtCore/qdir.h>
#include <QtWidgets/qboxlayout.h> #include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qfileiconprovider.h>
#include <FramelessWidgetsHelper> #include <FramelessWidgetsHelper>
#include <StandardTitleBar> #include <StandardTitleBar>
#include <StandardSystemButton> #include <StandardSystemButton>
@ -64,9 +65,11 @@ void MainWindow::closeEvent(QCloseEvent *event)
void MainWindow::initialize() void MainWindow::initialize()
{ {
resize(800, 600);
setWindowTitle(tr("FramelessHelper demo application - QOpenGLWidget")); setWindowTitle(tr("FramelessHelper demo application - QOpenGLWidget"));
setWindowIcon(QFileIconProvider().icon(QFileIconProvider::Computer));
resize(800, 600);
m_titleBar = new StandardTitleBar(this); m_titleBar = new StandardTitleBar(this);
m_titleBar->setWindowIconVisible(true);
m_glWidget = new GLWidget(this); m_glWidget = new GLWidget(this);
const auto mainLayout = new QVBoxLayout(this); const auto mainLayout = new QVBoxLayout(this);
mainLayout->setSpacing(0); mainLayout->setSpacing(0);

View File

@ -32,7 +32,7 @@ set(SOURCES
) )
if(${QT_VERSION} VERSION_LESS 6.2) if(${QT_VERSION} VERSION_LESS 6.2)
list(APPEND SOURCES qml.qrc) list(APPEND SOURCES resources.qrc)
endif() endif()
if(WIN32) if(WIN32)
@ -56,6 +56,10 @@ if(${QT_VERSION} VERSION_GREATER_EQUAL 6.2)
#ENABLE_TYPE_COMPILER # We can't use it for now due to it still can't compile singletons. #ENABLE_TYPE_COMPILER # We can't use it for now due to it still can't compile singletons.
# There's some hope to get it supported in Qt 6.5. # There's some hope to get it supported in Qt 6.5.
) )
qt_add_resources(Quick resources
PREFIX "/Demo"
FILES "images/microsoft.svg"
)
endif() endif()
target_link_libraries(Quick PRIVATE target_link_libraries(Quick PRIVATE

View File

@ -111,5 +111,7 @@ FramelessWindow {
left: parent.left left: parent.left
right: parent.right right: parent.right
} }
windowIcon: "qrc:///Demo/images/microsoft.svg"
windowIconVisible: true
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg t="1661848097607" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3344" width="512" height="512" xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M0 0h486.592v486.592H0z" fill="#F25022" p-id="3345"/>
<path d="M537.408 0H1024v486.592H537.408z" fill="#7FBA00" p-id="3346"/>
<path d="M0 537.408h486.592V1024H0z" fill="#00A4EF" p-id="3347"/>
<path d="M537.408 537.408H1024V1024H537.408z" fill="#FFB900" p-id="3348"/>
</svg>

After

Width:  |  Height:  |  Size: 636 B

View File

@ -1,5 +1,6 @@
<RCC> <RCC>
<qresource prefix="/Demo"> <qresource prefix="/Demo">
<file>images/microsoft.svg</file>
<file>MainWindow.qml</file> <file>MainWindow.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -35,6 +35,7 @@
#endif #endif
#include <QtWidgets/qlabel.h> #include <QtWidgets/qlabel.h>
#include <QtWidgets/qboxlayout.h> #include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qfileiconprovider.h>
#include <FramelessManager> #include <FramelessManager>
#include <Utils> #include <Utils>
#include <FramelessWidgetsHelper> #include <FramelessWidgetsHelper>
@ -83,8 +84,10 @@ void Widget::closeEvent(QCloseEvent *event)
void Widget::initialize() void Widget::initialize()
{ {
setWindowTitle(tr("FramelessHelper demo application - Qt Widgets")); setWindowTitle(tr("FramelessHelper demo application - Qt Widgets"));
setWindowIcon(QFileIconProvider().icon(QFileIconProvider::Computer));
resize(800, 600); resize(800, 600);
m_titleBar.reset(new StandardTitleBar(this)); m_titleBar.reset(new StandardTitleBar(this));
m_titleBar->setWindowIconVisible(true);
m_clockLabel.reset(new QLabel(this)); m_clockLabel.reset(new QLabel(this));
m_clockLabel->setFrameShape(QFrame::NoFrame); m_clockLabel->setFrameShape(QFrame::NoFrame);
QFont clockFont = font(); QFont clockFont = font();

View File

@ -206,9 +206,9 @@ Q_NAMESPACE_EXPORT(FRAMELESSHELPER_CORE_API)
[[maybe_unused]] static constexpr const int kDefaultWindowFrameBorderThickness = 1; [[maybe_unused]] static constexpr const int kDefaultWindowFrameBorderThickness = 1;
[[maybe_unused]] static constexpr const int kDefaultTitleBarFontPointSize = 11; [[maybe_unused]] static constexpr const int kDefaultTitleBarFontPointSize = 11;
[[maybe_unused]] static constexpr const int kDefaultTitleBarContentsMargin = 10; [[maybe_unused]] static constexpr const int kDefaultTitleBarContentsMargin = 10;
[[maybe_unused]] static constexpr const int kDefaultWindowIconSize = 16; [[maybe_unused]] static constexpr const QSize kDefaultWindowIconSize = {16, 16};
[[maybe_unused]] static constexpr const QSize kDefaultSystemButtonSize = {qRound(qreal(kDefaultTitleBarHeight) * 1.5), kDefaultTitleBarHeight}; [[maybe_unused]] static constexpr const QSize kDefaultSystemButtonSize = {qRound(qreal(kDefaultTitleBarHeight) * 1.5), kDefaultTitleBarHeight};
[[maybe_unused]] static constexpr const QSize kDefaultSystemButtonIconSize = {kDefaultWindowIconSize, kDefaultWindowIconSize}; [[maybe_unused]] static constexpr const QSize kDefaultSystemButtonIconSize = kDefaultWindowIconSize;
[[maybe_unused]] static constexpr const QSize kDefaultWindowSize = {160, 160}; // Value taken from QPA. [[maybe_unused]] static constexpr const QSize kDefaultWindowSize = {160, 160}; // Value taken from QPA.
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))

View File

@ -0,0 +1 @@
#include <quickimageitem.h>

View File

@ -0,0 +1,74 @@
/*
* MIT License
*
* Copyright (C) 2022 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 "framelesshelperquick_global.h"
#include <QtCore/qobject.h>
#include <QtCore/qpointer.h>
#include <QtCore/qvariant.h>
#include <QtGui/qpixmap.h>
#include <QtGui/qicon.h>
FRAMELESSHELPER_BEGIN_NAMESPACE
class QuickImageItem;
class FRAMELESSHELPER_QUICK_API QuickImageItemPrivate : public QObject
{
Q_OBJECT
Q_DISABLE_COPY_MOVE(QuickImageItemPrivate)
Q_DECLARE_PUBLIC(QuickImageItem)
public:
explicit QuickImageItemPrivate(QuickImageItem *q);
~QuickImageItemPrivate() override;
Q_NODISCARD static QuickImageItemPrivate *get(QuickImageItem *q);
Q_NODISCARD static const QuickImageItemPrivate *get(const QuickImageItem *q);
void paint(QPainter *painter);
Q_NODISCARD QVariant source() const;
void setSource(const QVariant &value);
private:
void initialize();
void fromUrl(const QUrl &value, QPainter *painter);
void fromString(const QString &value, QPainter *painter);
void fromImage(const QImage &value, QPainter *painter);
void fromPixmap(const QPixmap &value, QPainter *painter);
void fromIcon(const QIcon &value, QPainter *painter);
Q_NODISCARD QRect paintArea() const;
private:
QPointer<QuickImageItem> q_ptr = nullptr;
QVariant m_source = {};
QPixmap m_pixmap = {};
QIcon m_icon = {};
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickImageItemPrivate))

View File

@ -37,6 +37,7 @@ QT_END_NAMESPACE
FRAMELESSHELPER_BEGIN_NAMESPACE FRAMELESSHELPER_BEGIN_NAMESPACE
class QuickStandardSystemButton; class QuickStandardSystemButton;
class QuickImageItem;
class FRAMELESSHELPER_QUICK_API QuickStandardTitleBar : public QQuickRectangle class FRAMELESSHELPER_QUICK_API QuickStandardTitleBar : public QQuickRectangle
{ {
@ -53,6 +54,9 @@ class FRAMELESSHELPER_QUICK_API QuickStandardTitleBar : public QQuickRectangle
Q_PROPERTY(bool extended READ isExtended WRITE setExtended NOTIFY extendedChanged FINAL) Q_PROPERTY(bool extended READ isExtended WRITE setExtended NOTIFY extendedChanged FINAL)
Q_PROPERTY(bool hideWhenClose READ isHideWhenClose WRITE setHideWhenClose NOTIFY hideWhenCloseChanged FINAL) Q_PROPERTY(bool hideWhenClose READ isHideWhenClose WRITE setHideWhenClose NOTIFY hideWhenCloseChanged FINAL)
Q_PROPERTY(QuickChromePalette* chromePalette READ chromePalette CONSTANT FINAL) Q_PROPERTY(QuickChromePalette* chromePalette READ chromePalette CONSTANT FINAL)
Q_PROPERTY(QSizeF windowIconSize READ windowIconSize WRITE setWindowIconSize NOTIFY windowIconSizeChanged FINAL)
Q_PROPERTY(bool windowIconVisible READ windowIconVisible WRITE setWindowIconVisible NOTIFY windowIconVisibleChanged FINAL)
Q_PROPERTY(QVariant windowIcon READ windowIcon WRITE setWindowIcon NOTIFY windowIconChanged FINAL)
public: public:
explicit QuickStandardTitleBar(QQuickItem *parent = nullptr); explicit QuickStandardTitleBar(QQuickItem *parent = nullptr);
@ -74,6 +78,15 @@ public:
Q_NODISCARD QuickChromePalette *chromePalette() const; Q_NODISCARD QuickChromePalette *chromePalette() const;
Q_NODISCARD QSizeF windowIconSize() const;
void setWindowIconSize(const QSizeF &value);
Q_NODISCARD bool windowIconVisible() const;
void setWindowIconVisible(const bool value);
Q_NODISCARD QVariant windowIcon() const;
void setWindowIcon(const QVariant &value);
protected: protected:
void itemChange(const ItemChange change, const ItemChangeData &value) override; void itemChange(const ItemChange change, const ItemChangeData &value) override;
Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override; Q_NODISCARD bool eventFilter(QObject *object, QEvent *event) override;
@ -87,11 +100,15 @@ private Q_SLOTS:
void clickMaximizeButton(); void clickMaximizeButton();
void clickCloseButton(); void clickCloseButton();
void retranslateUi(); void retranslateUi();
void updateWindowIcon();
Q_SIGNALS: Q_SIGNALS:
void titleLabelAlignmentChanged(); void titleLabelAlignmentChanged();
void extendedChanged(); void extendedChanged();
void hideWhenCloseChanged(); void hideWhenCloseChanged();
void windowIconSizeChanged();
void windowIconVisibleChanged();
void windowIconChanged();
private: private:
void initialize(); void initialize();
@ -99,6 +116,7 @@ private:
private: private:
Qt::Alignment m_labelAlignment = {}; Qt::Alignment m_labelAlignment = {};
QScopedPointer<QuickImageItem> m_windowIcon;
QScopedPointer<QQuickLabel> m_windowTitleLabel; QScopedPointer<QQuickLabel> m_windowTitleLabel;
QScopedPointer<QQuickRow> m_systemButtonsRow; QScopedPointer<QQuickRow> m_systemButtonsRow;
QScopedPointer<QuickStandardSystemButton> m_minimizeButton; QScopedPointer<QuickStandardSystemButton> m_minimizeButton;

View File

@ -0,0 +1,67 @@
/*
* MIT License
*
* Copyright (C) 2022 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 "framelesshelperquick_global.h"
#include <QtCore/qloggingcategory.h>
#include <QtQuick/qquickpainteditem.h>
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQuickImageItem)
class QuickImageItemPrivate;
class FRAMELESSHELPER_QUICK_API QuickImageItem : public QQuickPaintedItem
{
Q_OBJECT
#ifdef QML_NAMED_ELEMENT
QML_NAMED_ELEMENT(ImageItem)
#endif
Q_DISABLE_COPY_MOVE(QuickImageItem)
Q_DECLARE_PRIVATE(QuickImageItem)
Q_PROPERTY(QVariant source READ source WRITE setSource NOTIFY sourceChanged FINAL)
public:
explicit QuickImageItem(QQuickItem *parent = nullptr);
~QuickImageItem() override;
void paint(QPainter *painter) override;
Q_NODISCARD QVariant source() const;
void setSource(const QVariant &value);
Q_SIGNALS:
void sourceChanged();
private:
QScopedPointer<QuickImageItemPrivate> d_ptr;
};
FRAMELESSHELPER_END_NAMESPACE
Q_DECLARE_METATYPE2(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickImageItem))
QML_DECLARE_TYPE(FRAMELESSHELPER_PREPEND_NAMESPACE(QuickImageItem))

View File

@ -67,6 +67,12 @@ public:
Q_NODISCARD bool titleLabelVisible() const; Q_NODISCARD bool titleLabelVisible() const;
void setTitleLabelVisible(const bool value); void setTitleLabelVisible(const bool value);
Q_NODISCARD QSize windowIconSize() const;
void setWindowIconSize(const QSize &value);
Q_NODISCARD bool windowIconVisible() const;
void setWindowIconVisible(const bool value);
public Q_SLOTS: public Q_SLOTS:
void updateMaximizeButton(); void updateMaximizeButton();
void updateTitleBarColor(); void updateTitleBarColor();
@ -90,6 +96,8 @@ private:
bool m_hideWhenClose = false; bool m_hideWhenClose = false;
QScopedPointer<ChromePalette> m_chromePalette; QScopedPointer<ChromePalette> m_chromePalette;
bool m_titleLabelVisible = true; bool m_titleLabelVisible = true;
QSize m_windowIconSize = {};
bool m_windowIconVisible = false;
}; };
FRAMELESSHELPER_END_NAMESPACE FRAMELESSHELPER_END_NAMESPACE

View File

@ -49,6 +49,8 @@ class FRAMELESSHELPER_WIDGETS_API StandardTitleBar : public QWidget
Q_PROPERTY(bool hideWhenClose READ isHideWhenClose WRITE setHideWhenClose NOTIFY hideWhenCloseChanged FINAL) Q_PROPERTY(bool hideWhenClose READ isHideWhenClose WRITE setHideWhenClose NOTIFY hideWhenCloseChanged FINAL)
Q_PROPERTY(ChromePalette* chromePalette READ chromePalette CONSTANT FINAL) Q_PROPERTY(ChromePalette* chromePalette READ chromePalette CONSTANT FINAL)
Q_PROPERTY(bool titleLabelVisible READ titleLabelVisible WRITE setTitleLabelVisible NOTIFY titleLabelVisibleChanged FINAL) Q_PROPERTY(bool titleLabelVisible READ titleLabelVisible WRITE setTitleLabelVisible NOTIFY titleLabelVisibleChanged FINAL)
Q_PROPERTY(QSize windowIconSize READ windowIconSize WRITE setWindowIconSize NOTIFY windowIconSizeChanged FINAL)
Q_PROPERTY(bool windowIconVisible READ windowIconVisible WRITE setWindowIconVisible NOTIFY windowIconVisibleChanged FINAL)
public: public:
explicit StandardTitleBar(QWidget *parent = nullptr); explicit StandardTitleBar(QWidget *parent = nullptr);
@ -72,6 +74,12 @@ public:
Q_NODISCARD bool titleLabelVisible() const; Q_NODISCARD bool titleLabelVisible() const;
void setTitleLabelVisible(const bool value); void setTitleLabelVisible(const bool value);
Q_NODISCARD QSize windowIconSize() const;
void setWindowIconSize(const QSize &value);
Q_NODISCARD bool windowIconVisible() const;
void setWindowIconVisible(const bool value);
protected: protected:
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
@ -80,6 +88,8 @@ Q_SIGNALS:
void titleLabelAlignmentChanged(); void titleLabelAlignmentChanged();
void hideWhenCloseChanged(); void hideWhenCloseChanged();
void titleLabelVisibleChanged(); void titleLabelVisibleChanged();
void windowIconSizeChanged();
void windowIconVisibleChanged();
private: private:
QScopedPointer<StandardTitleBarPrivate> d_ptr; QScopedPointer<StandardTitleBarPrivate> d_ptr;

View File

@ -385,9 +385,8 @@ static inline void expblur(QImage &img, qreal radius, const bool improvedQuality
if (p) { if (p) {
p->save(); p->save();
p->scale(scale, scale); p->scale(scale, scale);
p->setRenderHint(QPainter::Antialiasing, false); p->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing
p->setRenderHint(QPainter::TextAntialiasing, false); | QPainter::SmoothPixmapTransform, quality);
p->setRenderHint(QPainter::SmoothPixmapTransform, false);
#if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 2, 0))
const QSize imageSize = blurImage.deviceIndependentSize().toSize(); const QSize imageSize = blurImage.deviceIndependentSize().toSize();
#else #else
@ -538,7 +537,7 @@ void MicaMaterialPrivate::maybeGenerateBlurredWallpaper(const bool force)
g_micaMaterialData()->mutex.lock(); g_micaMaterialData()->mutex.lock();
QPainter painter(&g_micaMaterialData()->blurredWallpaper); QPainter painter(&g_micaMaterialData()->blurredWallpaper);
#if 1 #if 1
qt_blurImage(&painter, buffer, kDefaultBlurRadius, false, false); qt_blurImage(&painter, buffer, kDefaultBlurRadius, true, false);
#else #else
painter.drawImage(desktopOriginPoint, buffer); painter.drawImage(desktopOriginPoint, buffer);
#endif #endif

View File

@ -38,6 +38,7 @@ set(PUBLIC_HEADERS
${INCLUDE_PREFIX}/framelessquickutils.h ${INCLUDE_PREFIX}/framelessquickutils.h
${INCLUDE_PREFIX}/quickchromepalette.h ${INCLUDE_PREFIX}/quickchromepalette.h
${INCLUDE_PREFIX}/quickmicamaterial.h ${INCLUDE_PREFIX}/quickmicamaterial.h
${INCLUDE_PREFIX}/quickimageitem.h
) )
set(PUBLIC_HEADERS_ALIAS set(PUBLIC_HEADERS_ALIAS
@ -47,6 +48,7 @@ set(PUBLIC_HEADERS_ALIAS
${INCLUDE_PREFIX}/FramelessQuickUtils ${INCLUDE_PREFIX}/FramelessQuickUtils
${INCLUDE_PREFIX}/QuickChromePalette ${INCLUDE_PREFIX}/QuickChromePalette
${INCLUDE_PREFIX}/QuickMicaMaterial ${INCLUDE_PREFIX}/QuickMicaMaterial
${INCLUDE_PREFIX}/QuickImageItem
) )
set(PRIVATE_HEADERS set(PRIVATE_HEADERS
@ -56,6 +58,7 @@ set(PRIVATE_HEADERS
${INCLUDE_PREFIX}/private/framelessquickwindow_p.h ${INCLUDE_PREFIX}/private/framelessquickwindow_p.h
${INCLUDE_PREFIX}/private/framelessquickwindow_p_p.h ${INCLUDE_PREFIX}/private/framelessquickwindow_p_p.h
${INCLUDE_PREFIX}/private/quickmicamaterial_p.h ${INCLUDE_PREFIX}/private/quickmicamaterial_p.h
${INCLUDE_PREFIX}/private/quickimageitem_p.h
) )
set(SOURCES set(SOURCES
@ -68,6 +71,7 @@ set(SOURCES
quickchromepalette.cpp quickchromepalette.cpp
global.cpp global.cpp
quickmicamaterial.cpp quickmicamaterial.cpp
quickimageitem.cpp
) )
if(WIN32 AND NOT FRAMELESSHELPER_BUILD_STATIC) if(WIN32 AND NOT FRAMELESSHELPER_BUILD_STATIC)

View File

@ -27,6 +27,7 @@
#include "framelessquickutils.h" #include "framelessquickutils.h"
#include "quickchromepalette.h" #include "quickchromepalette.h"
#include "quickmicamaterial.h" #include "quickmicamaterial.h"
#include "quickimageitem.h"
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
# include "quickstandardsystembutton_p.h" # include "quickstandardsystembutton_p.h"
# include "quickstandardtitlebar_p.h" # include "quickstandardtitlebar_p.h"
@ -86,6 +87,7 @@ void FramelessHelper::Quick::registerTypes(QQmlEngine *engine)
qmlRegisterType<FramelessQuickHelper>(QUICK_URI_EXPAND("FramelessHelper")); qmlRegisterType<FramelessQuickHelper>(QUICK_URI_EXPAND("FramelessHelper"));
qmlRegisterType<QuickMicaMaterial>(QUICK_URI_EXPAND("MicaMaterial")); qmlRegisterType<QuickMicaMaterial>(QUICK_URI_EXPAND("MicaMaterial"));
qmlRegisterType<QuickImageItem>(QUICK_URI_EXPAND("ImageItem"));
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
qmlRegisterType<QuickStandardSystemButton>(QUICK_URI_EXPAND("StandardSystemButton")); qmlRegisterType<QuickStandardSystemButton>(QUICK_URI_EXPAND("StandardSystemButton"));

View File

@ -34,6 +34,8 @@
# include "framelessquickwindow_p_p.h" # include "framelessquickwindow_p_p.h"
# include "quickmicamaterial.h" # include "quickmicamaterial.h"
# include "quickmicamaterial_p.h" # include "quickmicamaterial_p.h"
# include "quickimageitem.h"
# include "quickimageitem_p.h"
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
FRAMELESSHELPER_BEGIN_NAMESPACE FRAMELESSHELPER_BEGIN_NAMESPACE
@ -89,6 +91,9 @@ void initialize()
qRegisterMetaType<QuickMicaMaterial>(); qRegisterMetaType<QuickMicaMaterial>();
qRegisterMetaType<QuickMicaMaterial *>(); qRegisterMetaType<QuickMicaMaterial *>();
qRegisterMetaType<QuickMicaMaterialPrivate>(); qRegisterMetaType<QuickMicaMaterialPrivate>();
qRegisterMetaType<QuickImageItem>();
qRegisterMetaType<QuickImageItem *>();
qRegisterMetaType<QuickImageItemPrivate>();
#endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #endif // (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
} }

View File

@ -0,0 +1,235 @@
/*
* MIT License
*
* Copyright (C) 2022 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 "quickimageitem.h"
#include "quickimageitem_p.h"
#include <QtCore/qdebug.h>
#include <QtGui/qpainter.h>
#include <QtGui/qimage.h>
FRAMELESSHELPER_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQuickImageItem, "wangwenx190.framelesshelper.quick.quickimageitem")
#define INFO qCInfo(lcQuickImageItem)
#define DEBUG qCDebug(lcQuickImageItem)
#define WARNING qCWarning(lcQuickImageItem)
#define CRITICAL qCCritical(lcQuickImageItem)
using namespace Global;
FRAMELESSHELPER_STRING_CONSTANT2(QrcPrefix, "qrc:")
FRAMELESSHELPER_STRING_CONSTANT2(FileSystemPrefix, ":")
FRAMELESSHELPER_STRING_CONSTANT2(UrlPrefix, ":///")
FRAMELESSHELPER_STRING_CONSTANT2(FilePathPrefix, ":/")
QuickImageItemPrivate::QuickImageItemPrivate(QuickImageItem *q) : QObject(q)
{
Q_ASSERT(q);
if (!q) {
return;
}
q_ptr = q;
initialize();
}
QuickImageItemPrivate::~QuickImageItemPrivate() = default;
QuickImageItemPrivate *QuickImageItemPrivate::get(QuickImageItem *q)
{
Q_ASSERT(q);
if (!q) {
return nullptr;
}
return q->d_func();
}
const QuickImageItemPrivate *QuickImageItemPrivate::get(const QuickImageItem *q)
{
Q_ASSERT(q);
if (!q) {
return nullptr;
}
return q->d_func();
}
void QuickImageItemPrivate::paint(QPainter *painter)
{
Q_ASSERT(painter);
if (!painter) {
return;
}
if (!m_source.isValid()) {
return;
}
painter->save();
painter->setRenderHints(QPainter::Antialiasing
| QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
switch (m_source.userType()) {
case QMetaType::QUrl:
fromUrl(m_source.toUrl(), painter);
break;
case QMetaType::QString:
fromString(m_source.toString(), painter);
break;
case QMetaType::QImage:
fromImage(qvariant_cast<QImage>(m_source), painter);
break;
case QMetaType::QPixmap:
fromPixmap(qvariant_cast<QPixmap>(m_source), painter);
break;
case QMetaType::QIcon:
fromIcon(qvariant_cast<QIcon>(m_source), painter);
break;
default:
WARNING << "Unsupported type:" << m_source.typeName();
break;
}
painter->restore();
}
QVariant QuickImageItemPrivate::source() const
{
return m_source;
}
void QuickImageItemPrivate::setSource(const QVariant &value)
{
Q_ASSERT(value.isValid());
if (!value.isValid()) {
return;
}
if (m_source == value) {
return;
}
m_source = value;
Q_Q(QuickImageItem);
q->update();
Q_EMIT q->sourceChanged();
}
void QuickImageItemPrivate::initialize()
{
Q_Q(QuickImageItem);
q->setAntialiasing(true);
q->setSmooth(true);
q->setMipmap(true);
q->setClip(true);
}
void QuickImageItemPrivate::fromUrl(const QUrl &value, QPainter *painter)
{
Q_ASSERT(value.isValid());
Q_ASSERT(painter);
if (!value.isValid() || !painter) {
return;
}
fromString((value.isLocalFile() ? value.toLocalFile() : value.toString()), painter);
}
void QuickImageItemPrivate::fromString(const QString &value, QPainter *painter)
{
Q_ASSERT(!value.isEmpty());
Q_ASSERT(painter);
if (value.isEmpty() || !painter) {
return;
}
return fromPixmap(QPixmap([&value]() -> QString {
QString path = value;
if (path.startsWith(kQrcPrefix, Qt::CaseInsensitive)) {
path.replace(kQrcPrefix, kFileSystemPrefix, Qt::CaseInsensitive);
}
if (path.startsWith(kUrlPrefix, Qt::CaseInsensitive)) {
path.replace(kUrlPrefix, kFilePathPrefix, Qt::CaseInsensitive);
}
return path;
}()), painter);
}
void QuickImageItemPrivate::fromImage(const QImage &value, QPainter *painter)
{
Q_ASSERT(!value.isNull());
Q_ASSERT(painter);
if (value.isNull() || !painter) {
return;
}
fromPixmap(QPixmap::fromImage(value), painter);
}
void QuickImageItemPrivate::fromPixmap(const QPixmap &value, QPainter *painter)
{
Q_ASSERT(!value.isNull());
Q_ASSERT(painter);
if (value.isNull() || !painter) {
return;
}
painter->drawPixmap(paintArea(), value);
}
void QuickImageItemPrivate::fromIcon(const QIcon &value, QPainter *painter)
{
Q_ASSERT(!value.isNull());
Q_ASSERT(painter);
if (value.isNull() || !painter) {
return;
}
value.paint(painter, paintArea());
}
QRect QuickImageItemPrivate::paintArea() const
{
Q_Q(const QuickImageItem);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
const QSize size = q->size().toSize();
#else
const QSize size = {qRound(q->width()), qRound(q->height())};
#endif
return {QPoint(0, 0), size};
}
QuickImageItem::QuickImageItem(QQuickItem *parent)
: QQuickPaintedItem(parent), d_ptr(new QuickImageItemPrivate(this))
{
}
QuickImageItem::~QuickImageItem() = default;
void QuickImageItem::paint(QPainter *painter)
{
Q_D(QuickImageItem);
d->paint(painter);
}
QVariant QuickImageItem::source() const
{
Q_D(const QuickImageItem);
return d->source();
}
void QuickImageItem::setSource(const QVariant &value)
{
Q_D(QuickImageItem);
d->setSource(value);
}
FRAMELESSHELPER_END_NAMESPACE

View File

@ -0,0 +1 @@
#include "../../include/FramelessHelper/Quick/quickimageitem.h"

View File

@ -0,0 +1 @@
#include "../../include/FramelessHelper/Quick/private/quickimageitem_p.h"

View File

@ -174,6 +174,8 @@ void QuickMicaMaterialPrivate::initialize()
{ {
Q_Q(QuickMicaMaterial); Q_Q(QuickMicaMaterial);
q->setFlag(QuickMicaMaterial::ItemHasContents); q->setFlag(QuickMicaMaterial::ItemHasContents);
q->setSmooth(true);
q->setAntialiasing(true);
q->setClip(true); q->setClip(true);
} }

View File

@ -197,6 +197,10 @@ void QuickStandardSystemButton::initialize()
{ {
FramelessManagerPrivate::initializeIconFont(); FramelessManagerPrivate::initializeIconFont();
setAntialiasing(true);
setSmooth(true);
setClip(true);
setImplicitWidth(kDefaultSystemButtonSize.width()); setImplicitWidth(kDefaultSystemButtonSize.width());
setImplicitHeight(kDefaultSystemButtonSize.height()); setImplicitHeight(kDefaultSystemButtonSize.height());

View File

@ -24,6 +24,7 @@
#include "quickstandardtitlebar_p.h" #include "quickstandardtitlebar_p.h"
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
#include "quickimageitem.h"
#include "quickstandardsystembutton_p.h" #include "quickstandardsystembutton_p.h"
#include "framelessquickwindow_p.h" #include "framelessquickwindow_p.h"
#include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquickitem_p.h>
@ -78,7 +79,11 @@ void QuickStandardTitleBar::setTitleLabelAlignment(const Qt::Alignment value)
labelAnchors->setBottomMargin(kDefaultTitleBarContentsMargin); labelAnchors->setBottomMargin(kDefaultTitleBarContentsMargin);
} }
if (m_labelAlignment & Qt::AlignLeft) { if (m_labelAlignment & Qt::AlignLeft) {
if (m_windowIcon->isVisible()) {
labelAnchors->setLeft(QQuickItemPrivate::get(m_windowIcon.data())->right());
} else {
labelAnchors->setLeft(titleBarPriv->left()); labelAnchors->setLeft(titleBarPriv->left());
}
labelAnchors->setLeftMargin(kDefaultTitleBarContentsMargin); labelAnchors->setLeftMargin(kDefaultTitleBarContentsMargin);
} }
if (m_labelAlignment & Qt::AlignRight) { if (m_labelAlignment & Qt::AlignRight) {
@ -152,6 +157,69 @@ QuickChromePalette *QuickStandardTitleBar::chromePalette() const
return m_chromePalette.data(); return m_chromePalette.data();
} }
QSizeF QuickStandardTitleBar::windowIconSize() const
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
return m_windowIcon->size();
#else
return {m_windowIcon->width(), m_windowIcon->height()};
#endif
}
void QuickStandardTitleBar::setWindowIconSize(const QSizeF &value)
{
Q_ASSERT(!value.isEmpty());
if (value.isEmpty()) {
return;
}
if (windowIconSize() == value) {
return;
}
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
m_windowIcon->setSize(value);
#else
m_windowIcon->setWidth(value.width());
m_windowIcon->setHeight(value.height());
#endif
Q_EMIT windowIconSizeChanged();
}
bool QuickStandardTitleBar::windowIconVisible() const
{
return m_windowIcon->isVisible();
}
void QuickStandardTitleBar::setWindowIconVisible(const bool value)
{
if (m_windowIcon->isVisible() == value) {
return;
}
m_windowIcon->setVisible(value);
QQuickAnchors *labelAnchors = QQuickItemPrivate::get(m_windowTitleLabel.data())->anchors();
if (value) {
labelAnchors->setLeft(QQuickItemPrivate::get(m_windowIcon.data())->right());
} else {
labelAnchors->setLeft(QQuickItemPrivate::get(this)->left());
}
}
QVariant QuickStandardTitleBar::windowIcon() const
{
return m_windowIcon->source();
}
void QuickStandardTitleBar::setWindowIcon(const QVariant &value)
{
Q_ASSERT(value.isValid());
if (!value.isValid()) {
return;
}
if (m_windowIcon->source() == value) {
return;
}
m_windowIcon->setSource(value);
}
void QuickStandardTitleBar::updateMaximizeButton() void QuickStandardTitleBar::updateMaximizeButton()
{ {
const QQuickWindow * const w = window(); const QQuickWindow * const w = window();
@ -270,8 +338,25 @@ void QuickStandardTitleBar::retranslateUi()
qobject_cast<QQuickToolTipAttached *>(qmlAttachedPropertiesObject<QQuickToolTip>(m_closeButton.data()))->setText(tr("Close")); qobject_cast<QQuickToolTipAttached *>(qmlAttachedPropertiesObject<QQuickToolTip>(m_closeButton.data()))->setText(tr("Close"));
} }
void QuickStandardTitleBar::updateWindowIcon()
{
// The user has set an icon explicitly, don't override it.
if (m_windowIcon->source().isValid()) {
return;
}
const QIcon icon = (window() ? window()->icon() : QIcon());
if (icon.isNull()) {
return;
}
m_windowIcon->setSource(icon);
}
void QuickStandardTitleBar::initialize() void QuickStandardTitleBar::initialize()
{ {
setSmooth(true);
setClip(true);
setAntialiasing(true);
m_chromePalette.reset(new QuickChromePalette(this)); m_chromePalette.reset(new QuickChromePalette(this));
connect(m_chromePalette.data(), &ChromePalette::titleBarColorChanged, connect(m_chromePalette.data(), &ChromePalette::titleBarColorChanged,
this, &QuickStandardTitleBar::updateTitleBarColor); this, &QuickStandardTitleBar::updateTitleBarColor);
@ -283,6 +368,16 @@ void QuickStandardTitleBar::initialize()
b->setColor(kDefaultTransparentColor); b->setColor(kDefaultTransparentColor);
setHeight(kDefaultTitleBarHeight); setHeight(kDefaultTitleBarHeight);
const QQuickItemPrivate * const thisPriv = QQuickItemPrivate::get(this);
m_windowIcon.reset(new QuickImageItem(this));
QQuickAnchors * const iconAnchors = QQuickItemPrivate::get(m_windowIcon.data())->anchors();
iconAnchors->setLeft(thisPriv->left());
iconAnchors->setLeftMargin(kDefaultTitleBarContentsMargin);
iconAnchors->setVerticalCenter(thisPriv->verticalCenter());
connect(m_windowIcon.data(), &QuickImageItem::visibleChanged, this, &QuickStandardTitleBar::windowIconVisibleChanged);
connect(m_windowIcon.data(), &QuickImageItem::sourceChanged, this, &QuickStandardTitleBar::windowIconChanged);
m_windowTitleLabel.reset(new QQuickLabel(this)); m_windowTitleLabel.reset(new QQuickLabel(this));
QFont f = m_windowTitleLabel->font(); QFont f = m_windowTitleLabel->font();
f.setPointSize(kDefaultTitleBarFontPointSize); f.setPointSize(kDefaultTitleBarFontPointSize);
@ -290,7 +385,6 @@ void QuickStandardTitleBar::initialize()
m_systemButtonsRow.reset(new QQuickRow(this)); m_systemButtonsRow.reset(new QQuickRow(this));
QQuickAnchors * const rowAnchors = QQuickItemPrivate::get(m_systemButtonsRow.data())->anchors(); QQuickAnchors * const rowAnchors = QQuickItemPrivate::get(m_systemButtonsRow.data())->anchors();
const QQuickItemPrivate * const thisPriv = QQuickItemPrivate::get(this);
rowAnchors->setTop(thisPriv->top()); rowAnchors->setTop(thisPriv->top());
rowAnchors->setRight(thisPriv->right()); rowAnchors->setRight(thisPriv->right());
m_minimizeButton.reset(new QuickStandardSystemButton(QuickGlobal::SystemButtonType::Minimize, m_systemButtonsRow.data())); m_minimizeButton.reset(new QuickStandardSystemButton(QuickGlobal::SystemButtonType::Minimize, m_systemButtonsRow.data()));
@ -300,6 +394,8 @@ void QuickStandardTitleBar::initialize()
m_closeButton.reset(new QuickStandardSystemButton(QuickGlobal::SystemButtonType::Close, m_systemButtonsRow.data())); m_closeButton.reset(new QuickStandardSystemButton(QuickGlobal::SystemButtonType::Close, m_systemButtonsRow.data()));
connect(m_closeButton.data(), &QuickStandardSystemButton::clicked, this, &QuickStandardTitleBar::clickCloseButton); connect(m_closeButton.data(), &QuickStandardSystemButton::clicked, this, &QuickStandardTitleBar::clickCloseButton);
setWindowIconSize(kDefaultWindowIconSize);
setWindowIconVisible(false);
setTitleLabelAlignment(Qt::AlignLeft | Qt::AlignVCenter); setTitleLabelAlignment(Qt::AlignLeft | Qt::AlignVCenter);
retranslateUi(); retranslateUi();
updateAll(); updateAll();
@ -342,6 +438,7 @@ bool QuickStandardTitleBar::eventFilter(QObject *object, QEvent *event)
void QuickStandardTitleBar::updateAll() void QuickStandardTitleBar::updateAll()
{ {
updateWindowIcon();
updateMaximizeButton(); updateMaximizeButton();
updateTitleLabelText(); updateTitleLabelText();
updateTitleBarColor(); updateTitleBarColor();

View File

@ -26,9 +26,8 @@
#include "standardtitlebar_p.h" #include "standardtitlebar_p.h"
#include "standardsystembutton.h" #include "standardsystembutton.h"
#include <QtCore/qcoreevent.h> #include <QtCore/qcoreevent.h>
#include <QtGui/qpainter.h>
#include <QtWidgets/qboxlayout.h> #include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qstyleoption.h>
#include <QtWidgets/qstylepainter.h>
FRAMELESSHELPER_BEGIN_NAMESPACE FRAMELESSHELPER_BEGIN_NAMESPACE
@ -126,16 +125,6 @@ void StandardTitleBarPrivate::paintTitleBar(QPaintEvent *event)
{ {
Q_UNUSED(event); Q_UNUSED(event);
Q_Q(StandardTitleBar); Q_Q(StandardTitleBar);
#if 0
// This block of code ensures that our widget can still apply the stylesheet correctly.
// Enabling the "Qt::WA_StyledBackground" attribute can also achieve the same
// effect, but since it's documented as only for internal uses, we use the
// public way to do that instead.
QStyleOption option;
option.initFrom(q);
QStylePainter painter(q);
painter.drawPrimitive(QStyle::PE_Widget, option);
#else
if (!m_window || m_chromePalette.isNull()) { if (!m_window || m_chromePalette.isNull()) {
return; return;
} }
@ -151,6 +140,17 @@ void StandardTitleBarPrivate::paintTitleBar(QPaintEvent *event)
painter.setRenderHints(QPainter::Antialiasing | painter.setRenderHints(QPainter::Antialiasing |
QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
painter.fillRect(QRect(QPoint(0, 0), q->size()), backgroundColor); painter.fillRect(QRect(QPoint(0, 0), q->size()), backgroundColor);
int titleLabelLeftOffset = 0;
if (m_windowIconVisible) {
const QIcon icon = m_window->windowIcon();
if (!icon.isNull()) {
const QSize size = (m_windowIconSize.isEmpty() ? kDefaultWindowIconSize : m_windowIconSize);
const int y = qRound(qreal(q->height() - size.height()) / qreal(2));
const QRect rect = {QPoint(kDefaultTitleBarContentsMargin, y), size};
titleLabelLeftOffset = (rect.left() + rect.width());
icon.paint(&painter, rect);
}
}
if (m_titleLabelVisible) { if (m_titleLabelVisible) {
const QString text = m_window->windowTitle(); const QString text = m_window->windowTitle();
if (!text.isEmpty()) { if (!text.isEmpty()) {
@ -161,12 +161,12 @@ void StandardTitleBarPrivate::paintTitleBar(QPaintEvent *event)
}(); }();
painter.setPen(foregroundColor); painter.setPen(foregroundColor);
painter.setFont(font); painter.setFont(font);
const QRect rect = [this, q]() -> QRect { const QRect rect = [this, q, titleLabelLeftOffset]() -> QRect {
const int w = q->width(); const int w = q->width();
int leftMargin = 0; int leftMargin = 0;
int rightMargin = 0; int rightMargin = 0;
if (m_labelAlignment & Qt::AlignLeft) { if (m_labelAlignment & Qt::AlignLeft) {
leftMargin = kDefaultTitleBarContentsMargin; leftMargin = (kDefaultTitleBarContentsMargin + titleLabelLeftOffset);
} }
if (m_labelAlignment & Qt::AlignRight) { if (m_labelAlignment & Qt::AlignRight) {
rightMargin = (w - m_minimizeButton->x() + kDefaultTitleBarContentsMargin); rightMargin = (w - m_minimizeButton->x() + kDefaultTitleBarContentsMargin);
@ -181,7 +181,6 @@ void StandardTitleBarPrivate::paintTitleBar(QPaintEvent *event)
} }
} }
painter.restore(); painter.restore();
#endif
} }
bool StandardTitleBarPrivate::titleLabelVisible() const bool StandardTitleBarPrivate::titleLabelVisible() const
@ -200,6 +199,42 @@ void StandardTitleBarPrivate::setTitleLabelVisible(const bool value)
Q_EMIT q->titleLabelVisibleChanged(); Q_EMIT q->titleLabelVisibleChanged();
} }
QSize StandardTitleBarPrivate::windowIconSize() const
{
return m_windowIconSize;
}
void StandardTitleBarPrivate::setWindowIconSize(const QSize &value)
{
Q_ASSERT(!value.isEmpty());
if (value.isEmpty()) {
return;
}
if (m_windowIconSize == value) {
return;
}
m_windowIconSize = value;
Q_Q(StandardTitleBar);
q->update();
Q_EMIT q->windowIconSizeChanged();
}
bool StandardTitleBarPrivate::windowIconVisible() const
{
return m_windowIconVisible;
}
void StandardTitleBarPrivate::setWindowIconVisible(const bool value)
{
if (m_windowIconVisible == value) {
return;
}
m_windowIconVisible = value;
Q_Q(StandardTitleBar);
q->update();
Q_EMIT q->windowIconVisibleChanged();
}
void StandardTitleBarPrivate::updateMaximizeButton() void StandardTitleBarPrivate::updateMaximizeButton()
{ {
const bool max = m_window->isMaximized(); const bool max = m_window->isMaximized();
@ -286,6 +321,10 @@ void StandardTitleBarPrivate::initialize()
this, &StandardTitleBarPrivate::updateChromeButtonColor); this, &StandardTitleBarPrivate::updateChromeButtonColor);
q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
q->setFixedHeight(kDefaultTitleBarHeight); q->setFixedHeight(kDefaultTitleBarHeight);
connect(m_window, &QWidget::windowIconChanged, this, [q](const QIcon &icon){
Q_UNUSED(icon);
q->update();
});
connect(m_window, &QWidget::windowTitleChanged, this, [q](const QString &title){ connect(m_window, &QWidget::windowTitleChanged, this, [q](const QString &title){
Q_UNUSED(title); Q_UNUSED(title);
q->update(); q->update();
@ -415,6 +454,30 @@ void StandardTitleBar::setTitleLabelVisible(const bool value)
d->setTitleLabelVisible(value); d->setTitleLabelVisible(value);
} }
QSize StandardTitleBar::windowIconSize() const
{
Q_D(const StandardTitleBar);
return d->windowIconSize();
}
void StandardTitleBar::setWindowIconSize(const QSize &value)
{
Q_D(StandardTitleBar);
d->setWindowIconSize(value);
}
bool StandardTitleBar::windowIconVisible() const
{
Q_D(const StandardTitleBar);
return d->windowIconVisible();
}
void StandardTitleBar::setWindowIconVisible(const bool value)
{
Q_D(StandardTitleBar);
d->setWindowIconVisible(value);
}
void StandardTitleBar::paintEvent(QPaintEvent *event) void StandardTitleBar::paintEvent(QPaintEvent *event)
{ {
Q_D(StandardTitleBar); Q_D(StandardTitleBar);