author | zecke <zecke> | 2004-04-03 18:20:07 (UTC) |
---|---|---|
committer | zecke <zecke> | 2004-04-03 18:20:07 (UTC) |
commit | 93aeaa0de75ba89bd565c845e79e470a80816b0a (patch) (unidiff) | |
tree | 3e15f667c53a3906d0b6ae29dfb0f82df00bfbd1 /noncore/tools/clock/analogclock.cpp | |
parent | c836722793b20c17908e55a4fcc0061b814ae1f6 (diff) | |
download | opie-93aeaa0de75ba89bd565c845e79e470a80816b0a.zip opie-93aeaa0de75ba89bd565c845e79e470a80816b0a.tar.gz opie-93aeaa0de75ba89bd565c845e79e470a80816b0a.tar.bz2 |
Initial revision
Diffstat (limited to 'noncore/tools/clock/analogclock.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/tools/clock/analogclock.cpp | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/noncore/tools/clock/analogclock.cpp b/noncore/tools/clock/analogclock.cpp new file mode 100644 index 0000000..bf358e2 --- a/dev/null +++ b/noncore/tools/clock/analogclock.cpp | |||
@@ -0,0 +1,203 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of the Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | |||
21 | #include "analogclock.h" | ||
22 | |||
23 | #include <qlayout.h> | ||
24 | #include <qpainter.h> | ||
25 | #include <qtopia/global.h> | ||
26 | |||
27 | #include <math.h> | ||
28 | |||
29 | const double deg2rad = 0.017453292519943295769;// pi/180 | ||
30 | |||
31 | AnalogClock::AnalogClock( QWidget *parent, const char *name ) | ||
32 | : QFrame( parent, name ), clear(false) | ||
33 | { | ||
34 | setMinimumSize(50,50); | ||
35 | } | ||
36 | |||
37 | QSizePolicy AnalogClock::sizePolicy() const | ||
38 | { | ||
39 | return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); | ||
40 | } | ||
41 | |||
42 | void AnalogClock::drawContents( QPainter *p ) | ||
43 | { | ||
44 | #if !defined(NO_DEBUG) | ||
45 | static bool first = true; | ||
46 | if ( first ) { | ||
47 | QTOPIA_PROFILE("first paint event"); | ||
48 | first = false; | ||
49 | } | ||
50 | #endif | ||
51 | |||
52 | QRect r = contentsRect(); | ||
53 | |||
54 | if ( r.width() < r.height() ) { | ||
55 | r.setY( (r.height() - r.width())/2 ); | ||
56 | r.setHeight( r.width() ); | ||
57 | } | ||
58 | |||
59 | QPoint center( r.x() + r.width() / 2, r.y() + r.height() / 2 ); | ||
60 | |||
61 | const int w_tick = r.width()/300+1; | ||
62 | const int w_sec = r.width()/400+1; | ||
63 | const int w_hour = r.width()/80+1; | ||
64 | |||
65 | QPoint l1( r.x() + r.width() / 2, r.y() + 2 ); | ||
66 | QPoint l2( r.x() + r.width() / 2, r.y() + 8 ); | ||
67 | |||
68 | QPoint h1( r.x() + r.width() / 2, r.y() + r.height() / 4 ); | ||
69 | QPoint h2( r.x() + r.width() / 2, r.y() + r.height() / 2 ); | ||
70 | |||
71 | QPoint m1( r.x() + r.width() / 2, r.y() + r.height() / 9 ); | ||
72 | QPoint m2( r.x() + r.width() / 2, r.y() + r.height() / 2 ); | ||
73 | |||
74 | QPoint s1( r.x() + r.width() / 2, r.y() + 8 ); | ||
75 | QPoint s2( r.x() + r.width() / 2, r.y() + r.height() / 2 ); | ||
76 | |||
77 | QColor color( clear ? backgroundColor() : black ); | ||
78 | QTime time = clear ? prevTime : currTime; | ||
79 | |||
80 | if ( clear && prevTime.secsTo(currTime) > 1 ) { | ||
81 | p->eraseRect( rect() ); | ||
82 | return; | ||
83 | } | ||
84 | |||
85 | if ( !clear ) { | ||
86 | // draw ticks | ||
87 | p->setPen( QPen( color, w_tick ) ); | ||
88 | for ( int i = 0; i < 12; i++ ) | ||
89 | p->drawLine( rotate( center, l1, i * 30 ), rotate( center, l2, i * 30 ) ); | ||
90 | } | ||
91 | |||
92 | if ( !clear || prevTime.minute() != currTime.minute() || | ||
93 | prevTime.hour() != currTime.hour() ) { | ||
94 | // draw hour pointer | ||
95 | h1 = rotate( center, h1, 30 * ( time.hour() % 12 ) + time.minute() / 2 ); | ||
96 | h2 = rotate( center, h2, 30 * ( time.hour() % 12 ) + time.minute() / 2 ); | ||
97 | p->setPen( color ); | ||
98 | p->setBrush( color ); | ||
99 | drawHand( p, h1, h2 ); | ||
100 | } | ||
101 | |||
102 | if ( !clear || prevTime.minute() != currTime.minute() ) { | ||
103 | // draw minute pointer | ||
104 | m1 = rotate( center, m1, time.minute() * 6 ); | ||
105 | m2 = rotate( center, m2, time.minute() * 6 ); | ||
106 | p->setPen( color ); | ||
107 | p->setBrush( color ); | ||
108 | drawHand( p, m1, m2 ); | ||
109 | } | ||
110 | |||
111 | // draw second pointer | ||
112 | s1 = rotate( center, s1, time.second() * 6 ); | ||
113 | s2 = rotate( center, s2, time.second() * 6 ); | ||
114 | p->setPen( QPen( color, w_sec ) ); | ||
115 | p->drawLine( s1, s2 ); | ||
116 | |||
117 | // cap | ||
118 | p->setBrush(color); | ||
119 | p->drawEllipse( center.x()-w_hour/2, center.y()-w_hour/2, w_hour, w_hour ); | ||
120 | |||
121 | if ( !clear ) | ||
122 | prevTime = currTime; | ||
123 | } | ||
124 | |||
125 | // Dijkstra's bisection algorithm to find the square root as an integer. | ||
126 | |||
127 | static uint int_sqrt(uint n) | ||
128 | { | ||
129 | if ( n >= UINT_MAX>>2 ) // n must be in the range 0...UINT_MAX/2-1 | ||
130 | return 2*int_sqrt( n/4 ); | ||
131 | uint h, p= 0, q= 1, r= n; | ||
132 | while ( q <= n ) | ||
133 | q <<= 2; | ||
134 | while ( q != 1 ) { | ||
135 | q >>= 2; | ||
136 | h= p + q; | ||
137 | p >>= 1; | ||
138 | if ( r >= h ) { | ||
139 | p += q; | ||
140 | r -= h; | ||
141 | } | ||
142 | } | ||
143 | return p; | ||
144 | } | ||
145 | |||
146 | void AnalogClock::drawHand( QPainter *p, QPoint p1, QPoint p2 ) | ||
147 | { | ||
148 | int hw = 7; | ||
149 | if ( contentsRect().height() < 100 ) | ||
150 | hw = 5; | ||
151 | |||
152 | int dx = p2.x() - p1.x(); | ||
153 | int dy = p2.y() - p1.y(); | ||
154 | int w = dx*dx+dy*dy; | ||
155 | int ix,iy; | ||
156 | w = int_sqrt(w*256); | ||
157 | iy = w ? (hw * dy * 16)/ w : dy ? 0 : hw; | ||
158 | ix = w ? (hw * dx * 16)/ w : dx ? 0 : hw; | ||
159 | |||
160 | // rounding dependent on sign | ||
161 | int nix, niy; | ||
162 | if ( ix < 0 ) { | ||
163 | nix = ix/2; | ||
164 | ix = (ix-1)/2; | ||
165 | } else { | ||
166 | nix = (ix+1)/2; | ||
167 | ix = ix/2; | ||
168 | } | ||
169 | if ( iy < 0 ) { | ||
170 | niy = iy/2; | ||
171 | iy = (iy-1)/2; | ||
172 | } else { | ||
173 | niy = (iy+1)/2; | ||
174 | iy = iy/2; | ||
175 | } | ||
176 | |||
177 | QPointArray pa(4); | ||
178 | pa[0] = p1; | ||
179 | pa[1] = QPoint( p2.x()+iy, p2.y()-nix ); | ||
180 | pa[2] = QPoint( p2.x()-niy, p2.y()+ix ); | ||
181 | pa[3] = p1; | ||
182 | |||
183 | p->drawPolygon( pa ); | ||
184 | } | ||
185 | |||
186 | void AnalogClock::display( const QTime& t ) | ||
187 | { | ||
188 | currTime = t; | ||
189 | clear = true; | ||
190 | repaint( false ); | ||
191 | clear = false; | ||
192 | repaint( false ); | ||
193 | } | ||
194 | |||
195 | QPoint AnalogClock::rotate( QPoint c, QPoint p, int a ) | ||
196 | { | ||
197 | double angle = deg2rad * ( - a + 180 ); | ||
198 | double nx = c.x() - ( p.x() - c.x() ) * cos( angle ) - | ||
199 | ( p.y() - c.y() ) * sin( angle ); | ||
200 | double ny = c.y() - ( p.y() - c.y() ) * cos( angle ) + | ||
201 | ( p.x() - c.x() ) * sin( angle ); | ||
202 | return QPoint( int(nx), int(ny) ); | ||
203 | } | ||