3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
10 #include <ui/qt/utils/color_utils.h>
11 #include <ui/qt/utils/tango_colors.h>
13 #include <QApplication>
16 #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
17 #include <QStyleHints>
18 #include <epan/prefs.h>
21 // Colors we use in various parts of the UI.
23 // New colors should be chosen from tango_colors.h. The expert and hidden
24 // colors come from the GTK+ UI and are grandfathered in.
26 // At some point we should probably make these configurable along with the
27 // graph and sequence colors.
29 const QColor
ColorUtils::expert_color_comment
= QColor (0xb7, 0xf7, 0x74); /* Green */
30 const QColor
ColorUtils::expert_color_chat
= QColor (0x80, 0xb7, 0xf7); /* Light blue */
31 const QColor
ColorUtils::expert_color_note
= QColor (0xa0, 0xff, 0xff); /* Bright turquoise */
32 const QColor
ColorUtils::expert_color_warn
= QColor (0xf7, 0xf2, 0x53); /* Yellow */
33 const QColor
ColorUtils::expert_color_error
= QColor (0xff, 0x5c, 0x5c); /* Pale red */
34 const QColor
ColorUtils::expert_color_foreground
= QColor (0x00, 0x00, 0x00); /* Black */
35 const QColor
ColorUtils::hidden_proto_item
= QColor (0x44, 0x44, 0x44); /* Gray */
37 ColorUtils::ColorUtils(QObject
*parent
) :
43 // A color_t has RGB values in [0,65535].
44 // Qt RGB colors have RGB values in [0,255].
46 // 65535/255 = 257 = 0x0101, so converting from [0,255] to
47 // [0,65535] involves just shifting the 8-bit value left 8 bits
48 // and ORing them together.
50 // Converting from [0,65535] to [0,255] without rounding involves
51 // just shifting the 16-bit value right 8 bits; I guess you could
52 // round them by adding 0x80 to the value before shifting.
54 QColor
ColorUtils::fromColorT (const color_t
*color
) {
55 if (!color
) return QColor();
56 // Convert [0,65535] values to [0,255] values
57 return QColor(color
->red
>> 8, color
->green
>> 8, color
->blue
>> 8);
60 QColor
ColorUtils::fromColorT(color_t color
)
62 return fromColorT(&color
);
65 const color_t
ColorUtils::toColorT(const QColor color
)
69 // Convert [0,255] values to [0,65535] values
70 colort
.red
= (color
.red() << 8) | color
.red();
71 colort
.green
= (color
.green() << 8) | color
.green();
72 colort
.blue
= (color
.blue() << 8) | color
.blue();
77 QRgb
ColorUtils::alphaBlend(const QColor
&color1
, const QColor
&color2
, qreal alpha
)
79 alpha
= qBound(qreal(0.0), alpha
, qreal(1.0));
81 int r1
= color1
.red() * alpha
;
82 int g1
= color1
.green() * alpha
;
83 int b1
= color1
.blue() * alpha
;
84 int r2
= color2
.red() * (1 - alpha
);
85 int g2
= color2
.green() * (1 - alpha
);
86 int b2
= color2
.blue() * (1 - alpha
);
88 QColor
alpha_color(r1
+ r2
, g1
+ g2
, b1
+ b2
);
89 return alpha_color
.rgb();
92 QRgb
ColorUtils::alphaBlend(const QBrush
&brush1
, const QBrush
&brush2
, qreal alpha
)
94 return alphaBlend(brush1
.color(), brush2
.color(), alpha
);
97 QList
<QRgb
> ColorUtils::graph_colors_
;
98 const QList
<QRgb
> ColorUtils::graphColors()
100 if (graph_colors_
.isEmpty()) {
101 // Available graph colors
103 graph_colors_
= QList
<QRgb
>()
104 << tango_aluminium_6
// Bar outline (use black instead)?
108 << tango_scarlet_red_5
115 << tango_scarlet_red_3
119 return graph_colors_
;
122 QRgb
ColorUtils::graphColor(int item
)
124 if (graph_colors_
.isEmpty()) graphColors(); // Init list.
125 return graph_colors_
[item
% graph_colors_
.size()];
128 QList
<QRgb
> ColorUtils::sequence_colors_
;
129 QRgb
ColorUtils::sequenceColor(int item
)
131 if (sequence_colors_
.isEmpty()) {
132 // Available sequence colors. Copied from gtk/graph_analysis.c.
134 sequence_colors_
= QList
<QRgb
>()
135 << qRgb(144, 238, 144)
136 << qRgb(255, 160, 123)
137 << qRgb(255, 182, 193)
138 << qRgb(250, 250, 210)
139 << qRgb(255, 255, 52)
140 << qRgb(103, 205, 170)
141 << qRgb(224, 255, 255)
142 << qRgb(176, 196, 222)
143 << qRgb(135, 206, 254)
144 << qRgb(211, 211, 211);
146 return sequence_colors_
[item
% sequence_colors_
.size()];
149 bool ColorUtils::themeIsDark()
151 #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
152 switch (qApp
->styleHints()->colorScheme()) {
153 case Qt::ColorScheme::Dark
:
155 case Qt::ColorScheme::Light
:
157 case Qt::ColorScheme::Unknown
:
161 return qApp
->palette().windowText().color().lightness() > qApp
->palette().window().color().lightness();
164 #if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
165 void ColorUtils::setScheme(int scheme
)
168 case COLOR_SCHEME_LIGHT
:
169 qApp
->styleHints()->setColorScheme(Qt::ColorScheme::Light
);
171 case COLOR_SCHEME_DARK
:
172 qApp
->styleHints()->setColorScheme(Qt::ColorScheme::Dark
);
174 case COLOR_SCHEME_DEFAULT
:
176 qApp
->styleHints()->setColorScheme(Qt::ColorScheme::Unknown
);
180 void ColorUtils::setScheme(int)
185 QBrush
ColorUtils::themeLinkBrush()
187 return qApp
->palette().link();
190 QString
ColorUtils::themeLinkStyle()
195 link_style
= QStringLiteral("<style>a:link { color: %1; }</style>")
196 .arg(themeLinkBrush().color().name());
201 const QColor
ColorUtils::contrastingTextColor(const QColor color
)
203 bool background_is_light
= color
.lightness() > 127;
204 if ( (background_is_light
&& !ColorUtils::themeIsDark()) || (!background_is_light
&& ColorUtils::themeIsDark()) ) {
205 // usually black/darker color in light mode and white/lighter color in dark mode
206 return QApplication::palette().text().color();
208 // usually white/lighter color in light mode and black/darker color in dark mode
209 return QApplication::palette().base().color();
212 const QColor
ColorUtils::hoverBackground()
214 QPalette hover_palette
= QApplication::palette();
215 #if defined(Q_OS_MAC)
216 hover_palette
.setCurrentColorGroup(QPalette::Active
);
217 return hover_palette
.highlight().color();
219 return ColorUtils::alphaBlend(hover_palette
.window(), hover_palette
.highlight(), 0.5);
223 const QColor
ColorUtils::warningBackground()
226 return QColor(tango_butter_6
);
228 return QColor(tango_butter_2
);
231 const QColor
ColorUtils::disabledForeground()
233 return alphaBlend(QApplication::palette().windowText(), QApplication::palette().window(), 0.65);