1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
/****************************************************************************
**
** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
**
** This file is part of an example program for Qt. This example
** program may be used, distributed and modified without limitation.
**
*****************************************************************************/
#include "aclock.h"
#include <qtimer.h>
#include <qpainter.h>
#include <qbitmap.h>
//
// Constructs an analog clock widget that uses an internal QTimer.
//
AnalogClock::AnalogClock( QWidget *parent, const char *name )
: QWidget( parent, name )
{
time = QTime::currentTime(); // get current time
internalTimer = new QTimer( this ); // create internal timer
connect( internalTimer, SIGNAL(timeout()), SLOT(timeout()) );
internalTimer->start( 5000 ); // emit signal every 5 seconds
}
void AnalogClock::mousePressEvent( QMouseEvent *e )
{
if(isTopLevel())
clickPos = e->pos() + QPoint(geometry().topLeft() - frameGeometry().topLeft());
}
void AnalogClock::mouseMoveEvent( QMouseEvent *e )
{
if(isTopLevel())
move( e->globalPos() - clickPos );
}
//
// The QTimer::timeout() signal is received by this slot.
//
//
// When we set an explicit time we don't want the timeout() slot to be
// called anymore as this relies on currentTime()
//
void AnalogClock::setTime( const QTime & t )
{
time = t;
disconnect( internalTimer, SIGNAL(timeout()), this, SLOT(timeout()) );
if (autoMask())
updateMask();
else
update();
}
void AnalogClock::timeout()
{
QTime old_time = time;
time = QTime::currentTime();
if ( old_time.minute() != time.minute()
|| old_time.hour() != time.hour() ) { // minute or hour has changed
if (autoMask())
updateMask();
else
update();
}
}
void AnalogClock::paintEvent( QPaintEvent * )
{
if ( autoMask() )
return;
QPainter paint( this );
paint.setBrush( colorGroup().foreground() );
drawClock( &paint );
}
// If the clock is transparent, we use updateMask()
// instead of paintEvent()
void AnalogClock::updateMask() // paint clock mask
{
QBitmap bm( size() );
bm.fill( color0 ); //transparent
QPainter paint;
paint.begin( &bm, this );
paint.setBrush( color1 ); // use non-transparent color
paint.setPen( color1 );
drawClock( &paint );
paint.end();
setMask( bm );
}
//
// The clock is painted using a 1000x1000 square coordinate system, in
// the a centered square, as big as possible. The painter's pen and
// brush colors are used.
//
void AnalogClock::drawClock( QPainter *paint )
{
paint->save();
paint->setWindow( -500,-500, 1000,1000 );
QRect v = paint->viewport();
int d = QMIN( v.width(), v.height() );
paint->setViewport( v.left() + (v.width()-d)/2,
v.top() + (v.height()-d)/2, d, d );
QPointArray pts;
paint->save();
paint->rotate( 30*(time.hour()%12-3) + time.minute()/2 );
pts.setPoints( 4, -20,0, 0,-20, 300,0, 0,20 );
paint->drawConvexPolygon( pts );
paint->restore();
paint->save();
paint->rotate( (time.minute()-15)*6 );
pts.setPoints( 4, -10,0, 0,-10, 400,0, 0,10 );
paint->drawConvexPolygon( pts );
paint->restore();
for ( int i=0; i<12; i++ ) {
paint->drawLine( 440,0, 460,0 );
paint->rotate( 30 );
}
paint->restore();
}
void AnalogClock::setAutoMask(bool b)
{
if (b)
setBackgroundMode( PaletteForeground );
else
setBackgroundMode( PaletteBackground );
QWidget::setAutoMask(b);
}
|