]> cloud.milkyroute.net Git - dolphin.git/blob - src/selectionmode/backgroundcolorhelper.cpp
4477d0f2c1dedb4376067a934032f344acd47f0c
[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 if (!*i) {
58 i = m_colorControlledWidgets.erase(i);
59 continue;
60 }
61 setBackgroundColorForWidget(*i, m_backgroundColor);
62 }
63 }
64
65 void BackgroundColorHelper::updateBackgroundColor()
66 {
67 // We use colors from the color scheme for mixing so it fits the theme.
68 const auto colorScheme = KColorScheme(QPalette::Normal, KColorScheme::Window);
69 const auto activeBackgroundColor = colorScheme.background(KColorScheme::BackgroundRole::ActiveBackground).color();
70 // We use the positive color for mixing so the end product doesn't look like a warning or error.
71 const auto positiveBackgroundColor = colorScheme.background(KColorScheme::BackgroundRole::PositiveBackground).color();
72
73 // Make sure the new background color has a meaningfully different hue than the activeBackgroundColor.
74 const int hueDifference = positiveBackgroundColor.hue() - activeBackgroundColor.hue();
75 int newHue;
76 if (std::abs(hueDifference) > 80) {
77 newHue = (activeBackgroundColor.hue() + positiveBackgroundColor.hue()) / 2;
78 } else {
79 newHue = hueDifference > 0 ?
80 activeBackgroundColor.hue() + 40 :
81 activeBackgroundColor.hue() - 40;
82 newHue %= 360; // hue needs to be between 0 and 359 per Qt documentation.
83 }
84
85 m_backgroundColor = QColor::fromHsv(newHue,
86 // Saturation should be closer to the active color because otherwise the selection mode color might overpower it.
87 .7 * activeBackgroundColor.saturation() + .3 * positiveBackgroundColor.saturation(),
88 (activeBackgroundColor.value() + positiveBackgroundColor.value()) / 2,
89 (activeBackgroundColor.alpha() + positiveBackgroundColor.alpha()) / 2);
90 }
91
92 BackgroundColorHelper *BackgroundColorHelper::s_instance = nullptr;