1 // kclock - Clock screen saver for KDE
3 // Copyright (c) 2003, 2006, 2007, 2008 Melchior FRANZ <mfranz # kde : org>
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include <QGridLayout>
23 #include <QHBoxLayout>
27 #include <QVBoxLayout>
29 #include <KColorButton>
34 #include <KMessageBox>
40 const int COLOR_BUTTON_WIDTH
= 80;
41 const int TIMER_INTERVAL
= 100;
42 const int MAX_CLOCK_SIZE
= 10;
43 const unsigned int DEFAULT_CLOCK_SIZE
= 8;
44 const bool DEFAULT_KEEP_CENTERED
= false;
48 class KClockSaverInterface
: public KScreenSaverInterface
{
50 virtual KAboutData
*aboutData() {
51 return new KAboutData("kclock.kss", 0, ki18n("Clock"), "2.0", ki18n("Clock"));
54 virtual KScreenSaver
*create(WId id
) {
55 return new KClockSaver(id
);
58 virtual QDialog
*setup() {
59 return new KClockSetup();
64 int main(int argc
, char *argv
[])
66 KClockSaverInterface kss
;
67 return kScreenSaverMain(argc
, argv
, kss
);
71 //-----------------------------------------------------------------------------
74 KClockSetup::KClockSetup(QWidget
*parent
) :
78 setCaption(i18n("Setup Clock Screen Saver"));
80 setButtons(Ok
|Cancel
|Help
);
85 setButtonText(Help
, i18n("A&bout"));
86 QWidget
*main
= new QWidget(this);
89 QVBoxLayout
*top
= new QVBoxLayout(main
);
91 QHBoxLayout
*hbox
= new QHBoxLayout
;
95 QGroupBox
*colgroup
= new QGroupBox(i18n("Colors"), main
);
96 QGridLayout
*grid
= new QGridLayout();
99 KColorButton
*colorButton
;
101 label
= new QLabel(i18n("&Hour-hand:"));
102 colorButton
= new KColorButton(_hourColor
);
103 colorButton
->setFixedWidth(COLOR_BUTTON_WIDTH
);
104 label
->setBuddy(colorButton
);
105 connect(colorButton
, SIGNAL(changed(const QColor
&)),
106 SLOT(slotHourColor(const QColor
&)));
107 grid
->addWidget(label
, 1, 1);
108 grid
->addWidget(colorButton
, 1, 2);
110 label
= new QLabel(i18n("&Minute-hand:"));
111 colorButton
= new KColorButton(_minColor
);
112 colorButton
->setFixedWidth(COLOR_BUTTON_WIDTH
);
113 label
->setBuddy(colorButton
);
114 connect(colorButton
, SIGNAL(changed(const QColor
&)),
115 SLOT(slotMinColor(const QColor
&)));
116 grid
->addWidget(label
, 2, 1);
117 grid
->addWidget(colorButton
, 2, 2);
119 label
= new QLabel(i18n("&Second-hand:"));
120 colorButton
= new KColorButton(_secColor
);
121 colorButton
->setFixedWidth(COLOR_BUTTON_WIDTH
);
122 label
->setBuddy(colorButton
);
123 connect(colorButton
, SIGNAL(changed(const QColor
&)),
124 SLOT(slotSecColor(const QColor
&)));
125 grid
->addWidget(label
, 3, 1);
126 grid
->addWidget(colorButton
, 3, 2);
128 label
= new QLabel(i18n("Scal&e:"));
129 colorButton
= new KColorButton(_scaleColor
);
130 colorButton
->setFixedWidth(COLOR_BUTTON_WIDTH
);
131 label
->setBuddy(colorButton
);
132 connect(colorButton
, SIGNAL(changed(const QColor
&)),
133 SLOT(slotScaleColor(const QColor
&)));
134 grid
->addWidget(label
, 4, 1);
135 grid
->addWidget(colorButton
, 4, 2);
137 label
= new QLabel(i18n("&Background:"));
138 colorButton
= new KColorButton(_bgndColor
);
139 colorButton
->setFixedWidth(COLOR_BUTTON_WIDTH
);
140 label
->setBuddy(colorButton
);
141 connect(colorButton
, SIGNAL(changed(const QColor
&)),
142 SLOT(slotBgndColor(const QColor
&)));
143 grid
->addWidget(label
, 5, 1);
144 grid
->addWidget(colorButton
, 5, 2);
146 hbox
->addWidget(colgroup
);
147 colgroup
->setLayout(grid
);
150 QWidget
*_preview
= new QWidget(main
);
151 _preview
->setFixedSize(220, 165);
153 _saver
= new KClockSaver(_preview
->winId());
154 hbox
->addWidget(_preview
);
156 label
= new QLabel(i18n("Si&ze:"), main
);
157 top
->addWidget(label
);
158 QSlider
*qs
= new QSlider(Qt::Horizontal
);
160 qs
->setRange(0, MAX_CLOCK_SIZE
);
161 qs
->setSliderPosition(_size
);
162 qs
->setTickInterval(1);
163 qs
->setTickPosition(QSlider::TicksBelow
);
164 connect(qs
, SIGNAL(valueChanged(int)), this, SLOT(slotSliderMoved(int)));
167 KHBox
*qsscale
= new KHBox(main
);
168 label
= new QLabel(i18n("Small"), qsscale
);
169 label
->setAlignment(Qt::AlignLeading
);
170 label
= new QLabel(i18n("Medium"), qsscale
);
171 label
->setAlignment(Qt::AlignHCenter
);
172 label
= new QLabel(i18n("Big"), qsscale
);
173 label
->setAlignment(Qt::AlignTrailing
);
174 top
->addWidget(qsscale
);
176 QCheckBox
*keepCentered
= new QCheckBox(i18n("&Keep clock centered"), main
);
177 keepCentered
->setChecked(_keepCentered
);
178 connect(keepCentered
, SIGNAL(stateChanged(int)), SLOT(slotKeepCenteredChanged(int)));
179 top
->addWidget(keepCentered
);
182 connect(this, SIGNAL(okClicked()), this, SLOT(slotOk()));
183 connect(this, SIGNAL(helpClicked()), this, SLOT(slotHelp()));
187 KClockSetup::~KClockSetup()
193 void KClockSetup::readSettings()
195 KConfigGroup
settings(KGlobal::config(), "Settings");
197 _keepCentered
= settings
.readEntry("KeepCentered", DEFAULT_KEEP_CENTERED
);
198 _size
= settings
.readEntry("Size", DEFAULT_CLOCK_SIZE
);
199 if (_size
> MAX_CLOCK_SIZE
)
200 _size
= MAX_CLOCK_SIZE
;
202 KConfigGroup
colors(KGlobal::config(), "Colors");
203 QColor c
= Qt::black
;
204 _bgndColor
= colors
.readEntry("Background", c
);
207 _scaleColor
= colors
.readEntry("Scale", c
);
208 _hourColor
= colors
.readEntry("HourHand", c
);
209 _minColor
= colors
.readEntry("MinuteHand", c
);
212 _secColor
= colors
.readEntry("SecondHand", c
);
215 _saver
->setBgndColor(_bgndColor
);
216 _saver
->setScaleColor(_scaleColor
);
217 _saver
->setHourColor(_hourColor
);
218 _saver
->setMinColor(_minColor
);
219 _saver
->setSecColor(_secColor
);
224 void KClockSetup::slotOk()
226 KConfigGroup
settings(KGlobal::config(), "Settings");
227 settings
.writeEntry("Size", _size
);
228 settings
.writeEntry("KeepCentered", _keepCentered
);
231 KConfigGroup
colors(KGlobal::config(), "Colors");
232 colors
.writeEntry("Background", _bgndColor
);
233 colors
.writeEntry("Scale", _scaleColor
);
234 colors
.writeEntry("HourHand", _hourColor
);
235 colors
.writeEntry("MinuteHand", _minColor
);
236 colors
.writeEntry("SecondHand", _secColor
);
242 void KClockSetup::slotHelp()
244 KMessageBox::about(this, "<qt>" + i18n(
245 "Clock Screen Saver<br>"
247 "<nobr>Melchior FRANZ (c) 2003, 2006, 2007</nobr>") +
248 "<br><a href=\"mailto:mfranz@kde.org\">mfranz@kde.org</a>"
249 "</qt>", QString(), KMessageBox::AllowLink
);
253 void KClockSetup::slotBgndColor(const QColor
&color
)
257 _saver
->setBgndColor(_bgndColor
);
261 void KClockSetup::slotScaleColor(const QColor
&color
)
265 _saver
->setScaleColor(_scaleColor
);
269 void KClockSetup::slotHourColor(const QColor
&color
)
273 _saver
->setHourColor(_hourColor
);
277 void KClockSetup::slotMinColor(const QColor
&color
)
281 _saver
->setMinColor(_minColor
);
285 void KClockSetup::slotSecColor(const QColor
&color
)
289 _saver
->setSecColor(_secColor
);
293 void KClockSetup::slotSliderMoved(int v
)
296 _saver
->resizeClock(_size
= v
);
300 void KClockSetup::slotKeepCenteredChanged(int c
)
303 _saver
->setKeepCentered(_keepCentered
= c
);
307 //-----------------------------------------------------------------------------
310 ClockPainter::ClockPainter(QPaintDevice
*device
, int diameter
) :
313 setRenderHint(QPainter::Antialiasing
);
314 translate(diameter
/ 2.0, diameter
/ 2.0);
315 scale(diameter
/ 2000.0, -diameter
/ 2000.0);
320 void ClockPainter::drawTick(double angle
, double from
, double to
, double width
, const QColor
&color
, bool shadow
)
323 rotate(90.0 - angle
);
327 setBrush(QColor(100, 100, 100));
331 drawRect(QRectF(from
, -width
/ 2.0, to
- from
, width
));
336 void ClockPainter::drawDisc(double width
, const QColor
&color
, bool shadow
)
340 setBrush(QColor(100, 100, 100));
344 drawEllipse(QRectF(-width
, -width
, 2.0 * width
, 2.0 * width
));
348 void ClockPainter::drawHand(double angle
, double length
, double width
, const QColor
&color
, bool disc
)
351 drawDisc(width
* 1.3, color
, true);
352 drawTick(angle
, 0.0, length
, width
, color
, true);
355 drawDisc(width
* 1.3, color
, false);
356 drawTick(angle
, 0.0, length
, width
, color
, false);
361 void ClockPainter::drawScale(const QColor
&color
)
363 for (int i
= 0; i
< 360; i
+= 6)
365 drawTick(i
, 920.0, 980.0, 15.0, color
);
367 drawTick(i
, 825.0, 980.0, 40.0, color
);
372 //-----------------------------------------------------------------------------
376 KClockSaver::KClockSaver(WId id
) :
385 setAttribute(Qt::WA_NoSystemBackground
);
386 setMinimumSize(50, 50);
390 QPalette p
= palette();
391 p
.setColor(backgroundRole(), _bgndColor
);
394 connect(&_timer
, SIGNAL(timeout()), this, SLOT(slotTimeout()));
399 void KClockSaver::readSettings()
401 KConfigGroup
settings(KGlobal::config(), "Settings");
402 _keepCentered
= settings
.readEntry("KeepCentered", DEFAULT_KEEP_CENTERED
);
403 _size
= settings
.readEntry("Size", DEFAULT_CLOCK_SIZE
);
404 if (_size
> MAX_CLOCK_SIZE
)
405 _size
= MAX_CLOCK_SIZE
;
407 KConfigGroup
colors(KGlobal::config(), "Colors");
408 QColor c
= Qt::black
;
409 setBgndColor(colors
.readEntry("Background", c
));
412 setScaleColor(colors
.readEntry("Scale", c
));
413 setHourColor(colors
.readEntry("HourHand", c
));
414 setMinColor(colors
.readEntry("MinuteHand", c
));
417 setSecColor(colors
.readEntry("SecondHand", c
));
421 void KClockSaver::setKeepCentered(bool b
)
425 _x
= (width() - _diameter
) / 2;
426 _y
= (height() - _diameter
) / 2;
432 void KClockSaver::resizeClock(int size
)
435 _diameter
= qMin(width(), height()) * (_size
+ 4) / 14;
436 _x
= (width() - _diameter
) / 2;
437 _y
= (height() - _diameter
) / 2;
442 void KClockSaver::resizeEvent(QResizeEvent
*)
448 void KClockSaver::showEvent(QShowEvent
*)
452 _timer
.start(TIMER_INTERVAL
);
456 void KClockSaver::hideEvent(QHideEvent
*)
462 void KClockSaver::slotTimeout()
464 QTime t
= QTime::currentTime();
469 _second
= _secColor
!= _bgndColor
? s
: 0;
471 _minute
= t
.minute();
473 if (!_keepCentered
) {
478 else if (_x
>= (i
= width() - _diameter
))
484 else if (_y
>= (i
= height() - _diameter
))
491 void KClockSaver::paintEvent(QPaintEvent
*)
493 double hour_angle
= _hour
* 30.0 + _minute
* .5 + _second
/ 120.0;
494 double minute_angle
= _minute
* 6.0 + _second
* .1;
495 double second_angle
= _second
* 6.0;
497 QImage
clock(_diameter
, _diameter
, QImage::Format_RGB32
);
498 ClockPainter
c(&clock
, _diameter
);
499 c
.fillRect(-1000, -1000, 2000, 2000, _bgndColor
);
501 if (_scaleColor
!= _bgndColor
)
502 c
.drawScale(_scaleColor
);
503 if (_hourColor
!= _bgndColor
)
504 c
.drawHand(hour_angle
, 600.0, 55.0, _hourColor
, false);
505 if (_minColor
!= _bgndColor
)
506 c
.drawHand(minute_angle
, 900.0, 40.0, _minColor
);
507 if (_secColor
!= _bgndColor
)
508 c
.drawHand(second_angle
, 900.0, 30.0, _secColor
);
511 p
.drawImage(_x
, _y
, clock
);
512 p
.eraseRect(0, 0, _x
, height()); // left ver
513 p
.eraseRect(_x
+ _diameter
, 0, width(), height()); // right ver
514 p
.eraseRect(_x
, 0, _diameter
, _y
); // top hor
515 p
.eraseRect(_x
, _y
+ _diameter
, _diameter
, height() - _y
- _diameter
); // bottom hor