Fix include
[kdeartwork.git] / kscreensaver / kdesavers / kclock.cpp
blobf752f0abcd43e377040cbe84680558ea190fb09d
1 // kclock - Clock screen saver for KDE
2 //
3 // Copyright (c) 2003, 2006, 2007 Melchior FRANZ <mfranz # kde : org>
4 //
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.
9 //
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.
19 #include <QCheckBox>
20 #include <QColor>
21 #include <QGridLayout>
22 #include <QGroupBox>
23 #include <QHBoxLayout>
24 #include <QLabel>
25 #include <QSlider>
26 #include <QVBoxLayout>
28 #include <KColorButton>
29 #include <KConfig>
30 #include <KGlobal>
31 #include <KHBox>
32 #include <KLocale>
33 #include <KMessageBox>
35 #include "kclock.h"
36 #include "kclock.moc"
40 const int COLOR_BUTTON_WIDTH = 80;
41 const int TIMER_INTERVAL = 2000;
42 const int MAX_CLOCK_SIZE = 10;
43 const unsigned int DEFAULT_CLOCK_SIZE = 8;
44 const bool DEFAULT_KEEP_CENTERED = false;
49 class KClockSaverInterface : public KScreenSaverInterface {
50 public:
51 virtual KAboutData* aboutData() {
52 return new KAboutData("kclock.kss", 0, ki18n("Clock"), "1.90", ki18n("Clock"));
55 virtual KScreenSaver* create(WId id) {
56 return new KClockSaver(id);
59 virtual QDialog* setup() {
60 return new KClockSetup();
65 int main(int argc, char *argv[])
67 KClockSaverInterface kss;
68 return kScreenSaverMain(argc, argv, kss);
74 //-----------------------------------------------------------------------------
76 KClockSetup::KClockSetup(QWidget *parent) :
77 KDialog(parent),
78 _saver(0)
80 setCaption(i18n("Setup Clock Screen Saver"));
81 setModal(true);
82 setButtons(Ok|Cancel|Help);
83 setDefaultButton(Ok);
85 readSettings();
87 setButtonText(Help, i18n("A&bout"));
88 QWidget *main = new QWidget(this);
89 setMainWidget(main);
91 QVBoxLayout *top = new QVBoxLayout(main);
93 QHBoxLayout *hbox = new QHBoxLayout;
94 top->addLayout(hbox);
97 QGroupBox *colgroup = new QGroupBox(i18n("Colors"), main);
98 QGridLayout *grid = new QGridLayout();
100 QLabel *label;
101 KColorButton *colorButton;
103 label = new QLabel(i18n("&Hour-hand:"));
104 colorButton = new KColorButton(_hourColor);
105 colorButton->setFixedWidth(COLOR_BUTTON_WIDTH);
106 label->setBuddy(colorButton);
107 connect(colorButton, SIGNAL(changed(const QColor &)),
108 SLOT(slotHourColor(const QColor &)));
109 grid->addWidget(label, 1, 1);
110 grid->addWidget(colorButton, 1, 2);
112 label = new QLabel(i18n("&Minute-hand:"));
113 colorButton = new KColorButton(_minColor);
114 colorButton->setFixedWidth(COLOR_BUTTON_WIDTH);
115 label->setBuddy(colorButton);
116 connect(colorButton, SIGNAL(changed(const QColor &)),
117 SLOT(slotMinColor(const QColor &)));
118 grid->addWidget(label, 2, 1);
119 grid->addWidget(colorButton, 2, 2);
121 label = new QLabel(i18n("&Second-hand:"));
122 colorButton = new KColorButton(_secColor);
123 colorButton->setFixedWidth(COLOR_BUTTON_WIDTH);
124 label->setBuddy(colorButton);
125 connect(colorButton, SIGNAL(changed(const QColor &)),
126 SLOT(slotSecColor(const QColor &)));
127 grid->addWidget(label, 3, 1);
128 grid->addWidget(colorButton, 3, 2);
130 label = new QLabel(i18n("Scal&e:"));
131 colorButton = new KColorButton(_scaleColor);
132 colorButton->setFixedWidth(COLOR_BUTTON_WIDTH);
133 label->setBuddy(colorButton);
134 connect(colorButton, SIGNAL(changed(const QColor &)),
135 SLOT(slotScaleColor(const QColor &)));
136 grid->addWidget(label, 4, 1);
137 grid->addWidget(colorButton, 4, 2);
139 label = new QLabel(i18n("&Background:"));
140 colorButton = new KColorButton(_bgndColor);
141 colorButton->setFixedWidth(COLOR_BUTTON_WIDTH);
142 label->setBuddy(colorButton);
143 connect(colorButton, SIGNAL(changed(const QColor &)),
144 SLOT(slotBgndColor(const QColor &)));
145 grid->addWidget(label, 5, 1);
146 grid->addWidget(colorButton, 5, 2);
148 hbox->addWidget(colgroup);
149 colgroup->setLayout(grid);
152 QWidget *_preview = new QWidget(main);
153 _preview->setFixedSize(220, 165);
154 _preview->show();
155 _saver = new KClockSaver(_preview->winId());
156 hbox->addWidget(_preview);
158 label = new QLabel(i18n("Si&ze:"), main);
159 top->addWidget(label);
160 QSlider *qs = new QSlider(Qt::Horizontal);
161 label->setBuddy(qs);
162 qs->setRange(0, MAX_CLOCK_SIZE);
163 qs->setSliderPosition(_size);
164 qs->setTickInterval(1);
165 qs->setTickPosition(QSlider::TicksBelow);
166 connect(qs, SIGNAL(valueChanged(int)), this, SLOT(slotSliderMoved(int)));
167 top->addWidget(qs);
169 KHBox *qsscale = new KHBox(main);
170 label = new QLabel(i18n("Small"), qsscale);
171 label->setAlignment(Qt::AlignLeading);
172 label = new QLabel(i18n("Medium"), qsscale);
173 label->setAlignment(Qt::AlignHCenter);
174 label = new QLabel(i18n("Big"), qsscale);
175 label->setAlignment(Qt::AlignTrailing);
176 top->addWidget(qsscale);
178 QCheckBox *keepCentered = new QCheckBox(i18n("&Keep clock centered"), main);
179 keepCentered->setChecked(_keepCentered);
180 connect(keepCentered, SIGNAL(stateChanged(int)), SLOT(slotKeepCenteredChanged(int)));
181 top->addWidget(keepCentered);
182 top->addStretch();
184 connect(this, SIGNAL(okClicked()), this, SLOT(slotOk()));
185 connect(this, SIGNAL(helpClicked()), this, SLOT(slotHelp()));
189 KClockSetup::~KClockSetup()
191 delete _saver;
195 void KClockSetup::readSettings()
197 KConfigGroup settings(KGlobal::config(), "Settings");
199 _keepCentered = settings.readEntry("KeepCentered", DEFAULT_KEEP_CENTERED);
200 _size = settings.readEntry("Size", DEFAULT_CLOCK_SIZE);
201 if (_size > MAX_CLOCK_SIZE)
202 _size = MAX_CLOCK_SIZE;
204 KConfigGroup colors(KGlobal::config(), "Colors");
205 QColor c = Qt::black;
206 _bgndColor = colors.readEntry("Background", c);
208 c = Qt::white;
209 _scaleColor = colors.readEntry("Scale", c);
210 _hourColor = colors.readEntry("HourHand", c);
211 _minColor = colors.readEntry("MinuteHand", c);
213 c = Qt::red;
214 _secColor = colors.readEntry("SecondHand", c);
216 if (_saver) {
217 _saver->setBgndColor(_bgndColor);
218 _saver->setScaleColor(_scaleColor);
219 _saver->setHourColor(_hourColor);
220 _saver->setMinColor(_minColor);
221 _saver->setSecColor(_secColor);
226 void KClockSetup::slotOk()
228 KConfigGroup settings(KGlobal::config(), "Settings");
229 settings.writeEntry("Size", _size);
230 settings.writeEntry("KeepCentered", _keepCentered);
231 settings.sync();
233 KConfigGroup colors(KGlobal::config(), "Colors");
234 colors.writeEntry("Background", _bgndColor);
235 colors.writeEntry("Scale", _scaleColor);
236 colors.writeEntry("HourHand", _hourColor);
237 colors.writeEntry("MinuteHand", _minColor);
238 colors.writeEntry("SecondHand", _secColor);
239 colors.sync();
240 accept();
244 void KClockSetup::slotHelp()
246 KMessageBox::about(this, "<qt>" + i18n(
247 "Clock Screen Saver<br>"
248 "Version 2.0<br>"
249 "<nobr>Melchior FRANZ (c) 2003, 2006, 2007</nobr>") +
250 "<br><a href=\"mailto:mfranz@kde.org\">mfranz@kde.org</a>"
251 "</qt>", QString(), KMessageBox::AllowLink);
255 void KClockSetup::slotBgndColor(const QColor &color)
257 _bgndColor = color;
258 if (_saver)
259 _saver->setBgndColor(_bgndColor);
263 void KClockSetup::slotScaleColor(const QColor &color)
265 _scaleColor = color;
266 if (_saver)
267 _saver->setScaleColor(_scaleColor);
271 void KClockSetup::slotHourColor(const QColor &color)
273 _hourColor = color;
274 if (_saver)
275 _saver->setHourColor(_hourColor);
279 void KClockSetup::slotMinColor(const QColor &color)
281 _minColor = color;
282 if (_saver)
283 _saver->setMinColor(_minColor);
287 void KClockSetup::slotSecColor(const QColor &color)
289 _secColor = color;
290 if (_saver)
291 _saver->setSecColor(_secColor);
295 void KClockSetup::slotSliderMoved(int v)
297 if (_saver)
298 _saver->resizeClock(_size = v);
302 void KClockSetup::slotKeepCenteredChanged(int c)
304 if (_saver)
305 _saver->setKeepCentered(_keepCentered = c);
312 //-----------------------------------------------------------------------------
314 ClockPainter::ClockPainter(QWidget *parent) :
315 QPainter(parent)
317 setRenderHint(QPainter::Antialiasing, true);
321 void ClockPainter::drawTick(double angle, double from, double to, double width, QColor color, bool shadow)
323 save();
324 rotate(90.0 - angle);
325 setPen(Qt::NoPen);
327 if (shadow) {
328 width += 1.0;
329 setBrush(QColor(100, 100, 100));
330 } else {
331 setBrush(color);
333 drawRect(QRectF(from, -width / 2.0, to - from, width));
334 restore();
338 void ClockPainter::drawDisc(double width, QColor color, bool shadow)
340 setPen(Qt::NoPen);
342 if (shadow) {
343 width += 1.0;
344 setBrush(QColor(100, 100, 100));
345 } else {
346 setBrush(color);
348 drawEllipse(QRectF(-width, -width, 2.0 * width, 2.0 * width));
352 void ClockPainter::drawHand(double angle, double length, double width, QColor color, bool disc)
354 if (disc)
355 drawDisc(width * 1.3, color, true);
356 drawTick(angle, 0.0, length, width, color, true);
358 if (disc)
359 drawDisc(width * 1.3, color, false);
360 drawTick(angle, 0.0, length, width, color, false);
365 void ClockPainter::drawScale(QColor color)
367 for (int i = 0; i < 360; i += 6)
368 if (i % 30)
369 drawTick(i, 920.0, 980.0, 15.0, color);
370 else
371 drawTick(i, 825.0, 980.0, 40.0, color);
378 //-----------------------------------------------------------------------------
380 ClockWidget::ClockWidget(QWidget *parent) :
381 QWidget(parent),
382 _hour(-1),
383 _minute(-1),
384 _second(-1),
385 _showSecond(true),
386 _scaleColor(Qt::white),
387 _hourColor(Qt::white),
388 _minColor(Qt::white),
389 _secColor(Qt::red)
391 _timer = new QTimer(this);
392 connect(_timer, SIGNAL(timeout()), this, SLOT(timerSlot()));
393 _timer->start(100);
394 timerSlot();
398 ClockWidget::~ClockWidget()
400 delete _timer;
404 void ClockWidget::timerSlot(void)
406 QTime t = QTime::currentTime();
407 int s = t.second();
408 if (s == _second)
409 return;
411 _second = _showSecond ? s : 0;
412 _second = s;
413 _hour = t.hour();
414 _minute = t.minute();
415 update();
419 void ClockWidget::paintEvent(QPaintEvent *)
421 double hour_angle = _hour * 30.0 + _minute * .5;
422 double minute_angle = _minute * 6.0 + _second * .1;
423 double second_angle = _second * 6.0;
425 ClockPainter clock(this);
426 clock.translate(width() / 2, height() / 2);
427 clock.scale(0.8 * qMin(width(), height()));
429 clock.drawScale(_scaleColor);
430 clock.drawHand(hour_angle, 600.0, 55.0, _hourColor, false);
431 clock.drawHand(minute_angle, 900.0, 40.0, _minColor);
432 clock.drawHand(second_angle, 900.0, 30.0, _secColor);
439 //-----------------------------------------------------------------------------
441 KClockSaver::KClockSaver(WId id) :
442 KScreenSaver(id),
443 _timer(this),
444 _xstep(1),
445 _ystep(-1),
446 _showSecond(true)
448 _background = new QWidget(this);
449 _background->setBackgroundRole(QPalette::Window);
450 _background->setAutoFillBackground(true);
451 _background->setFixedSize(width(), height());
453 _clock_widget = new ClockWidget(_background);
455 connect(&_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
456 _timer.start(TIMER_INTERVAL);
458 readSettings();
459 resizeClock(_size);
460 _background->show();
464 void KClockSaver::readSettings()
466 KConfigGroup settings(KGlobal::config(), "Settings");
467 _keepCentered = settings.readEntry("KeepCentered", DEFAULT_KEEP_CENTERED);
468 _size = settings.readEntry("Size", DEFAULT_CLOCK_SIZE);
469 if (_size > MAX_CLOCK_SIZE)
470 _size = MAX_CLOCK_SIZE;
472 KConfigGroup colors(KGlobal::config(), "Colors");
473 QColor c = Qt::black;
474 setBgndColor(colors.readEntry("Background", c));
476 c = Qt::white;
477 setScaleColor(colors.readEntry("Scale", c));
478 setHourColor(colors.readEntry("HourHand", c));
479 setMinColor(colors.readEntry("MinuteHand", c));
481 c = Qt::red;
482 setSecColor(colors.readEntry("SecondHand", c));
486 void KClockSaver::setKeepCentered(bool b)
488 _keepCentered = b;
489 if (b) {
490 _x = (width() - _diameter) / 2;
491 _y = (height() - _diameter) / 2;
492 _clock_widget->move(_x, _y);
497 void KClockSaver::resizeClock(int size)
499 _size = size;
500 _diameter = qMin(width(), height()) * (_size + 4) / 14;
501 _x = (width() - _diameter) / 2;
502 _y = (height() - _diameter) / 2;
504 _clock_widget->hide(); // FIXME hack around flicker problem
505 _clock_widget->setGeometry(_x, _y, _diameter, _diameter);
506 _clock_widget->show();
510 void KClockSaver::slotTimeout()
512 if (_keepCentered)
513 return;
515 int i;
516 _x += _xstep;
517 if (_x <= 0)
518 _x = 0, _xstep = 1;
519 else if (_x >= (i = width() - _diameter))
520 _x = i, _xstep = -1;
522 _y += _ystep;
523 if (_y <= 0)
524 _y = 0, _ystep = 1;
525 else if (_y >= (i = height() - _diameter))
526 _y = i, _ystep = -1;
528 _clock_widget->move(_x, _y);