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