KWidgetsAddons

kled.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 1998 Jörg Habenicht <j.habenicht@europemail.com>
4 SPDX-FileCopyrightText: 2010 Christoph Feck <cfeck@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#include "kled.h"
10
11#include <QImage>
12#include <QPainter>
13#include <QStyle>
14#include <QStyleOption>
15
16class KLedPrivate
17{
18public:
19 int darkFactor = 300;
20 QColor color;
21 KLed::State state = KLed::On;
22 KLed::Look look = KLed::Raised;
23 KLed::Shape shape = KLed::Circular;
24
25 QPixmap cachedPixmap[2]; // for both states
26};
27
29 : QWidget(parent)
30 , d(new KLedPrivate)
31{
33 updateAccessibleName();
34}
35
36KLed::KLed(const QColor &color, QWidget *parent)
37 : QWidget(parent)
38 , d(new KLedPrivate)
39{
40 setColor(color);
41 updateAccessibleName();
42}
43
44KLed::KLed(const QColor &color, State state, Look look, Shape shape, QWidget *parent)
45 : QWidget(parent)
46 , d(new KLedPrivate)
47{
48 d->state = (state == Off ? Off : On);
49 d->look = look;
50 d->shape = shape;
51
52 setColor(color);
53 updateAccessibleName();
54}
55
56KLed::~KLed() = default;
57
58KLed::State KLed::state() const
59{
60 return d->state;
61}
62
63KLed::Shape KLed::shape() const
64{
65 return d->shape;
66}
67
68QColor KLed::color() const
69{
70 return d->color;
71}
72
73KLed::Look KLed::look() const
74{
75 return d->look;
76}
77
79{
80 if (d->state == state) {
81 return;
82 }
83
84 d->state = (state == Off ? Off : On);
85 updateCachedPixmap();
86 updateAccessibleName();
87}
88
90{
91 if (d->shape == shape) {
92 return;
93 }
94
95 d->shape = shape;
96 updateCachedPixmap();
97}
98
99void KLed::setColor(const QColor &color)
100{
101 if (d->color == color) {
102 return;
103 }
104
105 d->color = color;
106 updateCachedPixmap();
107}
108
109void KLed::setDarkFactor(int darkFactor)
110{
111 if (d->darkFactor == darkFactor) {
112 return;
113 }
114
115 d->darkFactor = darkFactor;
116 updateCachedPixmap();
117}
118
119int KLed::darkFactor() const
120{
121 return d->darkFactor;
122}
123
125{
126 if (d->look == look) {
127 return;
128 }
129
130 d->look = look;
131 updateCachedPixmap();
132}
133
135{
136 d->state = (d->state == On ? Off : On);
137 updateCachedPixmap();
138 updateAccessibleName();
139}
140
142{
143 setState(On);
144}
145
147{
148 setState(Off);
149}
150
151void KLed::resizeEvent(QResizeEvent *)
152{
153 updateCachedPixmap();
154}
155
156QSize KLed::sizeHint() const
157{
158 QStyleOption option;
159 option.initFrom(this);
160 int iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, &option, this);
161 return QSize(iconSize, iconSize);
162}
163
164QSize KLed::minimumSizeHint() const
165{
166 return QSize(16, 16);
167}
168
169void KLed::updateAccessibleName()
170{
171#ifndef QT_NO_ACCESSIBILITY
172 QString onName = tr("LED on", "Accessible name of a Led whose state is on");
173 QString offName = tr("LED off", "Accessible name of a Led whose state is off");
174 QString lastName = accessibleName();
175
176 if (lastName.isEmpty() || lastName == onName || lastName == offName) {
177 // Accessible name has not been manually set.
178
179 setAccessibleName(d->state == On ? onName : offName);
180 }
181#endif
182}
183
184void KLed::updateCachedPixmap()
185{
186 d->cachedPixmap[Off] = QPixmap();
187 d->cachedPixmap[On] = QPixmap();
188 update();
189}
190
191void KLed::paintEvent(QPaintEvent *)
192{
193 if (!d->cachedPixmap[d->state].isNull()) {
194 QPainter painter(this);
195 painter.drawPixmap(1, 1, d->cachedPixmap[d->state]);
196 return;
197 }
198
199 QSize size(width() - 2, height() - 2);
200 if (d->shape == Circular) {
201 // Make sure the LED is round
202 const int dim = qMin(width(), height()) - 2;
203 size = QSize(dim, dim);
204 }
205 QPointF center(size.width() / 2.0, size.height() / 2.0);
206 const int smallestSize = qMin(size.width(), size.height());
207 QPainter painter;
208
210 image.fill(0);
211
212 QRadialGradient fillGradient(center, smallestSize / 2.0, QPointF(center.x(), size.height() / 3.0));
213 const QColor fillColor = d->state != Off ? d->color : d->color.darker(d->darkFactor);
214 fillGradient.setColorAt(0.0, fillColor.lighter(250));
215 fillGradient.setColorAt(0.5, fillColor.lighter(130));
216 fillGradient.setColorAt(1.0, fillColor);
217
218 QConicalGradient borderGradient(center, d->look == Sunken ? 90 : -90);
219 QColor borderColor = palette().color(QPalette::Dark);
220 if (d->state == On) {
221 QColor glowOverlay = fillColor;
222 glowOverlay.setAlpha(80);
223
224 // This isn't the fastest way, but should be "fast enough".
225 // It's also the only safe way to use QPainter::CompositionMode
227 QPainter p(&img);
228 QColor start = borderColor;
229 start.setAlpha(255); // opaque
230 p.fillRect(0, 0, 1, 1, start);
231 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
232 p.fillRect(0, 0, 1, 1, glowOverlay);
233 p.end();
234
235 borderColor = img.pixel(0, 0);
236 }
237 borderGradient.setColorAt(0.2, borderColor);
238 borderGradient.setColorAt(0.5, palette().color(QPalette::Light));
239 borderGradient.setColorAt(0.8, borderColor);
240
241 painter.begin(&image);
243 painter.setBrush(d->look == Flat ? QBrush(fillColor) : QBrush(fillGradient));
244 const QBrush penBrush = (d->look == Flat) ? QBrush(borderColor) : QBrush(borderGradient);
245 const qreal penWidth = smallestSize / 8.0;
246 painter.setPen(QPen(penBrush, penWidth));
247 QRectF r(penWidth / 2.0, penWidth / 2.0, size.width() - penWidth, size.height() - penWidth);
248 if (d->shape == Rectangular) {
249 painter.drawRect(r);
250 } else {
251 painter.drawEllipse(r);
252 }
253 painter.end();
254
255 d->cachedPixmap[d->state] = QPixmap::fromImage(image);
256 painter.begin(this);
257 painter.drawPixmap(1, 1, d->cachedPixmap[d->state]);
258 painter.end();
259}
260
261#include "moc_kled.cpp"
void on()
Sets the state of the widget to On.
Definition kled.cpp:141
void setColor(const QColor &color)
Set the color of the widget.
Definition kled.cpp:99
State
Status of the light is on/off.
Definition kled.h:49
Shape
Shades of the lamp.
Definition kled.h:56
void setDarkFactor(int darkFactor)
Sets the factor to darken the LED in KLed::Off state.
Definition kled.cpp:109
~KLed() override
Destroys the LED widget.
Look
Displays a flat, round or sunken LED.
Definition kled.h:64
void setShape(Shape shape)
Set the shape of the LED.
Definition kled.cpp:89
KLed(QWidget *parent=nullptr)
Constructs a green, round LED widget which will initially be turned on.
Definition kled.cpp:28
void off()
Sets the state of the widget to Off.
Definition kled.cpp:146
void setState(State state)
Sets the state of the widget to On or Off.
Definition kled.cpp:78
void toggle()
Toggles the state of the led from Off to On or vice versa.
Definition kled.cpp:134
void setLook(Look look)
Sets the look of the widget.
Definition kled.cpp:124
Q_SCRIPTABLE Q_NOREPLY void start()
QColor lighter(int factor) const const
void setAlpha(int alpha)
Format_ARGB32_Premultiplied
QString tr(const char *sourceText, const char *disambiguation, int n)
CompositionMode_SourceOver
bool begin(QPaintDevice *device)
void drawEllipse(const QPoint &center, int rx, int ry)
void drawPixmap(const QPoint &point, const QPixmap &pixmap)
void drawRect(const QRect &rectangle)
bool end()
void setBrush(Qt::BrushStyle style)
void setPen(Qt::PenStyle style)
void setRenderHint(RenderHint hint, bool on)
QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags)
bool isEmpty() const const
PM_SmallIconSize
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const const=0
void initFrom(const QWidget *widget)
QTextStream & center(QTextStream &stream)
QStyle * style() const const
void update()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Oct 11 2024 12:19:04 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.