1 // kclock - Clock screen saver for KDE
3 // Copyright (c) 2003, 2006, 2007 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>
26 #include <QVBoxLayout>
28 #include <KColorButton>
33 #include <KMessageBox>
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
{
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
) :
80 setCaption(i18n("Setup Clock Screen Saver"));
82 setButtons(Ok
|Cancel
|Help
);
87 setButtonText(Help
, i18n("A&bout"));
88 QWidget
*main
= new QWidget(this);
91 QVBoxLayout
*top
= new QVBoxLayout(main
);
93 QHBoxLayout
*hbox
= new QHBoxLayout
;
97 QGroupBox
*colgroup
= new QGroupBox(i18n("Colors"), main
);
98 QGridLayout
*grid
= new QGridLayout();
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);
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
);
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)));
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
);
184 connect(this, SIGNAL(okClicked()), this, SLOT(slotOk()));
185 connect(this, SIGNAL(helpClicked()), this, SLOT(slotHelp()));
189 KClockSetup::~KClockSetup()
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
);
209 _scaleColor
= colors
.readEntry("Scale", c
);
210 _hourColor
= colors
.readEntry("HourHand", c
);
211 _minColor
= colors
.readEntry("MinuteHand", c
);
214 _secColor
= colors
.readEntry("SecondHand", c
);
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
);
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
);
244 void KClockSetup::slotHelp()
246 KMessageBox::about(this, "<qt>" + i18n(
247 "Clock Screen Saver<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
)
259 _saver
->setBgndColor(_bgndColor
);
263 void KClockSetup::slotScaleColor(const QColor
&color
)
267 _saver
->setScaleColor(_scaleColor
);
271 void KClockSetup::slotHourColor(const QColor
&color
)
275 _saver
->setHourColor(_hourColor
);
279 void KClockSetup::slotMinColor(const QColor
&color
)
283 _saver
->setMinColor(_minColor
);
287 void KClockSetup::slotSecColor(const QColor
&color
)
291 _saver
->setSecColor(_secColor
);
295 void KClockSetup::slotSliderMoved(int v
)
298 _saver
->resizeClock(_size
= v
);
302 void KClockSetup::slotKeepCenteredChanged(int c
)
305 _saver
->setKeepCentered(_keepCentered
= c
);
312 //-----------------------------------------------------------------------------
314 ClockPainter::ClockPainter(QWidget
*parent
) :
317 setRenderHint(QPainter::Antialiasing
, true);
321 void ClockPainter::drawTick(double angle
, double from
, double to
, double width
, QColor color
, bool shadow
)
324 rotate(90.0 - angle
);
329 setBrush(QColor(100, 100, 100));
333 drawRect(QRectF(from
, -width
/ 2.0, to
- from
, width
));
338 void ClockPainter::drawDisc(double width
, QColor color
, bool shadow
)
344 setBrush(QColor(100, 100, 100));
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
)
355 drawDisc(width
* 1.3, color
, true);
356 drawTick(angle
, 0.0, length
, width
, color
, true);
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)
369 drawTick(i
, 920.0, 980.0, 15.0, color
);
371 drawTick(i
, 825.0, 980.0, 40.0, color
);
378 //-----------------------------------------------------------------------------
380 ClockWidget::ClockWidget(QWidget
*parent
) :
386 _scaleColor(Qt::white
),
387 _hourColor(Qt::white
),
388 _minColor(Qt::white
),
391 _timer
= new QTimer(this);
392 connect(_timer
, SIGNAL(timeout()), this, SLOT(timerSlot()));
398 ClockWidget::~ClockWidget()
404 void ClockWidget::timerSlot(void)
406 QTime t
= QTime::currentTime();
411 _second
= _showSecond
? s
: 0;
414 _minute
= t
.minute();
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
) :
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
);
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
));
477 setScaleColor(colors
.readEntry("Scale", c
));
478 setHourColor(colors
.readEntry("HourHand", c
));
479 setMinColor(colors
.readEntry("MinuteHand", c
));
482 setSecColor(colors
.readEntry("SecondHand", c
));
486 void KClockSaver::setKeepCentered(bool b
)
490 _x
= (width() - _diameter
) / 2;
491 _y
= (height() - _diameter
) / 2;
492 _clock_widget
->move(_x
, _y
);
497 void KClockSaver::resizeClock(int 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()
519 else if (_x
>= (i
= width() - _diameter
))
525 else if (_y
>= (i
= height() - _diameter
))
528 _clock_widget
->move(_x
, _y
);