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