diff options
Diffstat (limited to 'src/selectionmode/backgroundcolorhelper.cpp')
| -rw-r--r-- | src/selectionmode/backgroundcolorhelper.cpp | 90 |
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; |
