]> cloud.milkyroute.net Git - dolphin.git/blob - src/selectionmode/backgroundcolorhelper.cpp
fc540315253d06eb7f8b6f6f8d00604e095edfa0
[dolphin.git] / src / selectionmode / backgroundcolorhelper.cpp
1 /*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2022 Felix Ernst <felixernst@zohomail.eu>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7
8 #include "backgroundcolorhelper.h"
9
10 #include <KColorScheme>
11
12 #include <QGuiApplication>
13 #include <QPalette>
14 #include <QtGlobal>
15 #include <QWidget>
16
17 using namespace SelectionMode;
18
19 BackgroundColorHelper *BackgroundColorHelper::instance()
20 {
21 if (!s_instance) {
22 s_instance = new BackgroundColorHelper;
23 }
24 return s_instance;
25 }
26
27
28 void setBackgroundColorForWidget(QWidget *widget, QColor color)
29 {
30 QPalette palette;
31 palette.setBrush(QPalette::Active, QPalette::Window, color);
32 palette.setBrush(QPalette::Inactive, QPalette::Window, color);
33 palette.setBrush(QPalette::Disabled, QPalette::Window, color);
34 widget->setAutoFillBackground(true);
35 widget->setPalette(palette);
36 }
37
38 void BackgroundColorHelper::controlBackgroundColor(QWidget *widget)
39 {
40 setBackgroundColorForWidget(widget, m_backgroundColor);
41
42 Q_ASSERT_X(std::find(m_colorControlledWidgets.begin(), m_colorControlledWidgets.end(), widget) == m_colorControlledWidgets.end(), "controlBackgroundColor",
43 "Duplicate insertion is not necessary because the background color should already automatically update itself on paletteChanged");
44 m_colorControlledWidgets.emplace_back(widget);
45 }
46
47 BackgroundColorHelper::BackgroundColorHelper()
48 {
49 updateBackgroundColor();
50 QObject::connect(qApp, &QGuiApplication::paletteChanged, [=](){ slotPaletteChanged(); });
51 }
52
53 void BackgroundColorHelper::slotPaletteChanged()
54 {
55 updateBackgroundColor();
56 for (auto i = m_colorControlledWidgets.begin(); i != m_colorControlledWidgets.end(); ++i) {
57 while (!*i) {
58 i = m_colorControlledWidgets.erase(i);
59 if (i == m_colorControlledWidgets.end()) {
60 break;
61 }
62 }
63 setBackgroundColorForWidget(*i, m_backgroundColor);
64 }
65 }
66
67 void BackgroundColorHelper::updateBackgroundColor()
68 {
69 // We use colors from the color scheme for mixing so it fits the theme.
70 const auto colorScheme = KColorScheme(QPalette::Normal, KColorScheme::Window);
71 const auto activeBackgroundColor = colorScheme.background(KColorScheme::BackgroundRole::ActiveBackground).color();
72 // We use the positive color for mixing so the end product doesn't look like a warning or error.
73 const auto positiveBackgroundColor = colorScheme.background(KColorScheme::BackgroundRole::PositiveBackground).color();
74
75 // Make sure the new background color has a meaningfully different hue than the activeBackgroundColor.
76 const int hueDifference = positiveBackgroundColor.hue() - activeBackgroundColor.hue();
77 int newHue;
78 if (std::abs(hueDifference) > 80) {
79 newHue = (activeBackgroundColor.hue() + positiveBackgroundColor.hue()) / 2;
80 } else {
81 newHue = hueDifference > 0 ?
82 activeBackgroundColor.hue() + 40 :
83 activeBackgroundColor.hue() - 40;
84 newHue %= 360; // hue needs to be between 0 and 359 per Qt documentation.
85 }
86
87 m_backgroundColor = QColor::fromHsv(newHue,
88 // Saturation should be closer to the saturation of the active color
89 // because otherwise the selection mode color might overpower it.
90 .7 * activeBackgroundColor.saturation() + .3 * positiveBackgroundColor.saturation(),
91 (activeBackgroundColor.value() + positiveBackgroundColor.value()) / 2,
92 (activeBackgroundColor.alpha() + positiveBackgroundColor.alpha()) / 2);
93 }
94
95 BackgroundColorHelper *BackgroundColorHelper::s_instance = nullptr;