diff options
author | Sahil Gautam <sahil@libreoffice.org> | 2024-11-05 15:25:24 +0530 |
---|---|---|
committer | Heiko Tietze <heiko.tietze@documentfoundation.org> | 2024-11-06 20:50:32 +0100 |
commit | c85155cf6d43e328bfe31834a49fbfb55670e166 (patch) | |
tree | c51952e0382af8ff38418f32602223dad0509dfa /vcl | |
parent | 4bdb421440207c21bf2ea93fdf8a9494742beb08 (diff) |
tdf#158943 Libreoffice Theme Part 3: Qt Color Customization
Enable UI color customization in QT via the use of custom palettes and
custom style objects for the application, and the native widgets like
the menus and the menubar.
Menubar in `kf6` doesn't follow the set palette's colors anymore, maybe
some update from kde/qt (something to look into). Works fine for `kf5`.
ticket: https://bugs.kde.org/show_bug.cgi?id=493550
Change-Id: Ibedd6d66b8ea2855e049a85b3d51ea7e933b5c57
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168901
Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org>
Tested-by: Jenkins
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/Library_vclplug_qt5.mk | 1 | ||||
-rw-r--r-- | vcl/Library_vclplug_qt6.mk | 1 | ||||
-rw-r--r-- | vcl/inc/qt5/QtCustomStyle.hxx | 35 | ||||
-rw-r--r-- | vcl/inc/qt5/QtTools.hxx | 5 | ||||
-rw-r--r-- | vcl/inc/qt6/QtCustomStyle.hxx | 12 | ||||
-rw-r--r-- | vcl/qt5/QtCustomStyle.cxx | 150 | ||||
-rw-r--r-- | vcl/qt5/QtFrame.cxx | 9 | ||||
-rw-r--r-- | vcl/qt5/QtMenu.cxx | 10 | ||||
-rw-r--r-- | vcl/qt6/QtCustomStyle.cxx | 12 |
9 files changed, 229 insertions, 6 deletions
diff --git a/vcl/Library_vclplug_qt5.mk b/vcl/Library_vclplug_qt5.mk index a5c96989fba9..8870dfda6f2f 100644 --- a/vcl/Library_vclplug_qt5.mk +++ b/vcl/Library_vclplug_qt5.mk @@ -82,6 +82,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt5,\ vcl/qt5/QtBitmap \ vcl/qt5/QtBuilder \ vcl/qt5/QtClipboard \ + vcl/qt5/QtCustomStyle \ vcl/qt5/QtData \ vcl/qt5/QtDragAndDrop \ vcl/qt5/QtFilePicker \ diff --git a/vcl/Library_vclplug_qt6.mk b/vcl/Library_vclplug_qt6.mk index 4beecca87c71..c31efc27a490 100644 --- a/vcl/Library_vclplug_qt6.mk +++ b/vcl/Library_vclplug_qt6.mk @@ -81,6 +81,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_qt6,\ vcl/qt6/QtBitmap \ vcl/qt6/QtBuilder \ vcl/qt6/QtClipboard \ + vcl/qt6/QtCustomStyle \ vcl/qt6/QtData \ vcl/qt6/QtDragAndDrop \ vcl/qt6/QtFilePicker \ diff --git a/vcl/inc/qt5/QtCustomStyle.hxx b/vcl/inc/qt5/QtCustomStyle.hxx new file mode 100644 index 000000000000..feac764030a7 --- /dev/null +++ b/vcl/inc/qt5/QtCustomStyle.hxx @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <QtGui/QPainter> +#include <QtWidgets/QProxyStyle> +#include <QtWidgets/QStyleOption> + +class QtCustomStyle : public QProxyStyle +{ + inline static bool m_bDefaultPaletteLoaded = false; + inline static bool m_bIsCustomStyleSet = false; + +public: + QtCustomStyle(){}; + + void drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter, + const QWidget* widget = nullptr) const override; + + static QPalette customPalette(); + static QPalette GetMenuBarPalette(); + static QPalette GetMenuPalette(); + static bool IsSystemThemeChanged(); + + static void LoadCustomStyle(bool bDarkMode); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/qt5/QtTools.hxx b/vcl/inc/qt5/QtTools.hxx index 404fe4aa7967..dc21d62add3d 100644 --- a/vcl/inc/qt5/QtTools.hxx +++ b/vcl/inc/qt5/QtTools.hxx @@ -82,6 +82,11 @@ inline QColor toQColor(const Color& rColor) return QColor(rColor.GetRed(), rColor.GetGreen(), rColor.GetBlue(), rColor.GetAlpha()); } +inline Color toColor(const QColor& rColor) +{ + return Color(rColor.red(), rColor.green(), rColor.blue()); +} + Qt::DropActions toQtDropActions(sal_Int8 dragOperation); sal_Int8 toVclDropActions(Qt::DropActions dragOperation); sal_Int8 toVclDropAction(Qt::DropAction dragOperation); diff --git a/vcl/inc/qt6/QtCustomStyle.hxx b/vcl/inc/qt6/QtCustomStyle.hxx new file mode 100644 index 000000000000..fd0f7b64dbc3 --- /dev/null +++ b/vcl/inc/qt6/QtCustomStyle.hxx @@ -0,0 +1,12 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "../qt5/QtCustomStyle.hxx" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qt5/QtCustomStyle.cxx b/vcl/qt5/QtCustomStyle.cxx new file mode 100644 index 000000000000..259e3990be5b --- /dev/null +++ b/vcl/qt5/QtCustomStyle.cxx @@ -0,0 +1,150 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <IconThemeSelector.hxx> +#include <QtCustomStyle.hxx> +#include <QtFrame.hxx> +#include <QtWidgets/qdrawutil.h> +#include <QtWidgets/QApplication> +#include <vcl/themecolors.hxx> +#include <vcl/qt/QtUtils.hxx> + +void QtCustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption* option, + QPainter* painter, const QWidget* widget) const +{ + if (!ThemeColors::IsThemeLoaded() || IsSystemThemeChanged()) + { + QProxyStyle::drawPrimitive(element, option, painter, widget); + return; + } + + const ThemeColors& aThemeColors = ThemeColors::GetThemeColors(); + switch (element) + { + case PE_FrameTabWidget: + { + painter->save(); + QBrush aFillBrush(toQColor(aThemeColors.GetWindowColor())); + QStyleOption aOpt = *option; + qDrawWinPanel(painter, option->rect, option->palette, false, &aFillBrush); + painter->restore(); + break; + } + case PE_FrameFocusRect: + break; + default: + QProxyStyle::drawPrimitive(element, option, painter, widget); + } +} + +QPalette QtCustomStyle::customPalette() +{ + if (!ThemeColors::IsThemeLoaded()) + return QApplication::palette(); + + const ThemeColors& aThemeColors = ThemeColors::GetThemeColors(); + QPalette aPal; + + aPal.setColor(QPalette::Base, toQColor(aThemeColors.GetBaseColor())); + aPal.setColor(QPalette::Window, toQColor(aThemeColors.GetWindowColor())); + + aPal.setColor(QPalette::WindowText, toQColor(aThemeColors.GetWindowTextColor())); + aPal.setColor(QPalette::Disabled, QPalette::WindowText, + toQColor(aThemeColors.GetSeparatorColor())); + aPal.setColor(QPalette::Text, toQColor(aThemeColors.GetButtonTextColor())); + aPal.setColor(QPalette::ButtonText, toQColor(aThemeColors.GetButtonTextColor())); + aPal.setColor(QPalette::Disabled, QPalette::ButtonText, + toQColor(aThemeColors.GetDisabledTextColor())); + aPal.setColor(QPalette::PlaceholderText, toQColor(aThemeColors.GetWindowTextColor())); + aPal.setColor(QPalette::Button, toQColor(aThemeColors.GetButtonColor())); + aPal.setColor(QPalette::Highlight, toQColor(aThemeColors.GetAccentColor())); + + aPal.setColor(QPalette::Dark, toQColor(aThemeColors.GetShadeColor())); + aPal.setColor(QPalette::Midlight, toQColor(aThemeColors.GetShadeColor())); + aPal.setColor(QPalette::Light, toQColor(aThemeColors.GetWindowColor())); + aPal.setColor(QPalette::Shadow, toQColor(aThemeColors.GetWindowColor())); + + return aPal; +} + +QPalette QtCustomStyle::GetMenuBarPalette() +{ + if (!ThemeColors::IsThemeLoaded() || IsSystemThemeChanged()) + return QApplication::palette(); + + QPalette aPal; + const ThemeColors& aThemeColors = ThemeColors::GetThemeColors(); + + aPal.setColor(QPalette::Text, toQColor(aThemeColors.GetMenuBarTextColor())); + aPal.setColor(QPalette::ButtonText, toQColor(aThemeColors.GetMenuBarTextColor())); + aPal.setColor(QPalette::Window, toQColor(aThemeColors.GetMenuBarColor())); + aPal.setColor(QPalette::Highlight, toQColor(aThemeColors.GetMenuBarHighlightColor())); + aPal.setColor(QPalette::HighlightedText, toQColor(aThemeColors.GetMenuBarHighlightTextColor())); + + return aPal; +} + +QPalette QtCustomStyle::GetMenuPalette() +{ + if (!ThemeColors::IsThemeLoaded() || IsSystemThemeChanged()) + return QApplication::palette(); + + QPalette aPal; + const ThemeColors& aThemeColors = ThemeColors::GetThemeColors(); + + aPal.setColor(QPalette::Base, toQColor(aThemeColors.GetMenuColor())); + aPal.setColor(QPalette::Highlight, toQColor(aThemeColors.GetMenuHighlightColor())); + aPal.setColor(QPalette::HighlightedText, toQColor(aThemeColors.GetMenuHighlightTextColor())); + aPal.setColor(QPalette::Disabled, QPalette::WindowText, + toQColor(aThemeColors.GetDisabledTextColor())); + aPal.setColor(QPalette::Window, toQColor(aThemeColors.GetMenuColor())); + + aPal.setColor(QPalette::Text, toQColor(aThemeColors.GetMenuTextColor())); + aPal.setColor(QPalette::Disabled, QPalette::Text, + toQColor(aThemeColors.GetDisabledTextColor())); + aPal.setColor(QPalette::ButtonText, toQColor(aThemeColors.GetMenuTextColor())); + aPal.setColor(QPalette::WindowText, toQColor(aThemeColors.GetMenuTextColor())); + aPal.setColor(QPalette::Button, toQColor(aThemeColors.GetButtonColor())); + aPal.setColor(QPalette::Disabled, QPalette::ButtonText, + toQColor(aThemeColors.GetDisabledTextColor())); + + aPal.setColor(QPalette::Dark, toQColor(aThemeColors.GetMenuColor())); + aPal.setColor(QPalette::Midlight, toQColor(aThemeColors.GetMenuColor())); + aPal.setColor(QPalette::Light, toQColor(aThemeColors.GetMenuColor())); + aPal.setColor(QPalette::Shadow, toQColor(aThemeColors.GetMenuColor())); + + return aPal; +} + +bool QtCustomStyle::IsSystemThemeChanged() +{ + return QApplication::palette() != QtCustomStyle::customPalette(); +} + +void QtCustomStyle::LoadCustomStyle(bool bDarkMode) +{ + if (!ThemeColors::IsThemeLoaded() + || ThemeColors::IsAutomaticTheme(ThemeColors::GetThemeColors().GetThemeName())) + return; + + // don't set custom palette in case the system theme has been changed. + if (!(m_bIsCustomStyleSet && IsSystemThemeChanged())) + QApplication::setPalette(QtCustomStyle::customPalette()); + + QIcon::setThemeName(toQString(vcl::IconThemeSelector::GetIconThemeForDesktopEnvironment( + Application::GetDesktopEnvironment(), bDarkMode))); + + if (m_bIsCustomStyleSet) + return; + + QApplication::setStyle(new QtCustomStyle); + m_bIsCustomStyleSet = true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qt5/QtFrame.cxx b/vcl/qt5/QtFrame.cxx index 61903543bc9e..c8f0960bc6a3 100644 --- a/vcl/qt5/QtFrame.cxx +++ b/vcl/qt5/QtFrame.cxx @@ -17,6 +17,8 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <IconThemeSelector.hxx> +#include <QtCustomStyle.hxx> #include <QtFrame.hxx> #include <QtFrame.moc> @@ -29,7 +31,6 @@ #include <QtMenu.hxx> #include <QtSvpGraphics.hxx> #include <QtSystem.hxx> -#include <QtTools.hxx> #include <QtTransferable.hxx> #if CHECK_ANY_QT_USING_X11 #include <QtX11Support.hxx> @@ -1026,11 +1027,6 @@ void QtFrame::setInputLanguage(LanguageType nInputLanguage) CallCallback(SalEvent::InputLanguageChange, nullptr); } -static Color toColor(const QColor& rColor) -{ - return Color(rColor.red(), rColor.green(), rColor.blue()); -} - static bool toVclFont(const QFont& rQFont, const css::lang::Locale& rLocale, vcl::Font& rVclFont) { FontAttributes aFA; @@ -1068,6 +1064,7 @@ void QtFrame::UpdateSettings(AllSettings& rSettings) { if (QtData::noNativeControls()) return; + QtCustomStyle::LoadCustomStyle(GetUseDarkMode()); StyleSettings style(rSettings.GetStyleSettings()); const css::lang::Locale aLocale = rSettings.GetUILanguageTag().getLocale(); diff --git a/vcl/qt5/QtMenu.cxx b/vcl/qt5/QtMenu.cxx index 49cabbbc4548..0d273bf35a0c 100644 --- a/vcl/qt5/QtMenu.cxx +++ b/vcl/qt5/QtMenu.cxx @@ -7,6 +7,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <QtCustomStyle.hxx> +#include <vcl/themecolors.hxx> #include <QtMenu.hxx> #include <QtMenu.moc> @@ -482,6 +484,14 @@ void QtMenu::SetFrame(const SalFrame* pFrame) void QtMenu::DoFullMenuUpdate(Menu* pMenuBar) { + if (mpQMenuBar && ThemeColors::IsThemeLoaded() + && !ThemeColors::IsAutomaticTheme(ThemeColors::GetThemeColors().GetThemeName())) + mpQMenuBar->setPalette(QtCustomStyle::GetMenuBarPalette()); + + if (mpQMenu && ThemeColors::IsThemeLoaded() + && !ThemeColors::IsAutomaticTheme(ThemeColors::GetThemeColors().GetThemeName())) + mpQMenu->setPalette(QtCustomStyle::GetMenuPalette()); + // clear action groups since menu is rebuilt ResetAllActionGroups(); ShowCloseButton(false); diff --git a/vcl/qt6/QtCustomStyle.cxx b/vcl/qt6/QtCustomStyle.cxx new file mode 100644 index 000000000000..a42a98d8cbdd --- /dev/null +++ b/vcl/qt6/QtCustomStyle.cxx @@ -0,0 +1,12 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "../qt5/QtCustomStyle.cxx" + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |