┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/selectionmode/backgroundcolorhelper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/selectionmode/backgroundcolorhelper.cpp')
-rw-r--r--src/selectionmode/backgroundcolorhelper.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/selectionmode/backgroundcolorhelper.cpp b/src/selectionmode/backgroundcolorhelper.cpp
new file mode 100644
index 000000000..8a7d69758
--- /dev/null
+++ b/src/selectionmode/backgroundcolorhelper.cpp
@@ -0,0 +1,90 @@
+/*
+ This file is part of the KDE project
+ SPDX-FileCopyrightText: 2022 Felix Ernst <[email protected]>
+
+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
+*/
+
+#include "backgroundcolorhelper.h"
+
+#include <KColorScheme>
+
+#include <QGuiApplication>
+#include <QPalette>
+#include <QtGlobal>
+#include <QWidget>
+
+BackgroundColorHelper *BackgroundColorHelper::instance()
+{
+ if (!s_instance) {
+ s_instance = new BackgroundColorHelper;
+ }
+ return s_instance;
+}
+
+
+void setBackgroundColorForWidget(QWidget *widget, QColor color)
+{
+ QPalette palette;
+ palette.setBrush(QPalette::Active, QPalette::Window, color);
+ palette.setBrush(QPalette::Inactive, QPalette::Window, color);
+ palette.setBrush(QPalette::Disabled, QPalette::Window, color);
+ widget->setAutoFillBackground(true);
+ widget->setPalette(palette);
+}
+
+void BackgroundColorHelper::controlBackgroundColor(QWidget *widget)
+{
+ setBackgroundColorForWidget(widget, m_backgroundColor);
+
+ Q_ASSERT_X(std::find(m_colorControlledWidgets.begin(), m_colorControlledWidgets.end(), widget) == m_colorControlledWidgets.end(), "controlBackgroundColor",
+ "Duplicate insertion is not necessary because the background color should already automatically update itself on paletteChanged");
+ m_colorControlledWidgets.emplace_back(widget);
+}
+
+BackgroundColorHelper::BackgroundColorHelper()
+{
+ updateBackgroundColor();
+ QObject::connect(qApp, &QGuiApplication::paletteChanged, [=](){ slotPaletteChanged(); });
+}
+
+void BackgroundColorHelper::slotPaletteChanged()
+{
+ updateBackgroundColor();
+ for (auto i = m_colorControlledWidgets.begin(); i != m_colorControlledWidgets.end(); ++i) {
+ if (!*i) {
+ i = m_colorControlledWidgets.erase(i);
+ continue;
+ }
+ setBackgroundColorForWidget(*i, m_backgroundColor);
+ }
+}
+
+void BackgroundColorHelper::updateBackgroundColor()
+{
+ // We use colors from the color scheme for mixing so it fits the theme.
+ const auto colorScheme = KColorScheme(QPalette::Normal, KColorScheme::Window);
+ const auto activeBackgroundColor = colorScheme.background(KColorScheme::BackgroundRole::ActiveBackground).color();
+ // We use the positive color for mixing so the end product doesn't look like a warning or error.
+ const auto positiveBackgroundColor = colorScheme.background(KColorScheme::BackgroundRole::PositiveBackground).color();
+
+ // Make sure the new background color has a meaningfully different hue than the activeBackgroundColor.
+ const int hueDifference = positiveBackgroundColor.hue() - activeBackgroundColor.hue();
+ int newHue;
+ if (std::abs(hueDifference) > 80) {
+ newHue = (activeBackgroundColor.hue() + positiveBackgroundColor.hue()) / 2;
+ } else {
+ newHue = hueDifference > 0 ?
+ activeBackgroundColor.hue() + 40 :
+ activeBackgroundColor.hue() - 40;
+ newHue %= 360; // hue needs to be between 0 and 359 per Qt documentation.
+ }
+
+ m_backgroundColor = QColor::fromHsv(newHue,
+ // Saturation should be closer to the active color because otherwise the selection mode color might overpower it.
+ .7 * activeBackgroundColor.saturation() + .3 * positiveBackgroundColor.saturation(),
+ (activeBackgroundColor.value() + positiveBackgroundColor.value()) / 2,
+ (activeBackgroundColor.alpha() + positiveBackgroundColor.alpha()) / 2);
+}
+
+BackgroundColorHelper *BackgroundColorHelper::s_instance = nullptr;