package AnalogClock; use TQt; use TQt::isa qw(TQt::Widget); use TQt::slots setTime => ['const TQTime&'], drawClock => ['TQPainter*'], timeout => []; use TQt::attributes qw( clickPos _time ); # # Constructs an analog clock widget that uses an internal TQTimer # sub NEW { shift->SUPER::NEW(@_); _time = TQt::Time::currentTime(); # get current time my $internalTimer = TQt::Timer(this); # create internal timer this->connect($internalTimer, TQT_SIGNAL('timeout()'), TQT_SLOT('timeout()')); $internalTimer->start(5000); # emit signal every 5 seconds } sub mousePressEvent { my $e = shift; if(isTopLevel()) { # Lack of operators is really noticable here my $topLeft = TQt::Point( geometry()->topLeft->x - frameGeometry()->topLeft->x, geometry()->topLeft->y - frameGeometry()->topLeft->y ); clickPos = TQt::Point($e->pos->x + $topLeft->x, $e->pos->y + $topLeft->y); } } sub mouseMoveEvent { my $e = shift; if(isTopLevel()) { move(TQt::Point($e->globalPos->x - clickPos->x, $e->globalPos->y - clickPos->y)); } } sub setTime { my $t = shift; timeout(); } # # The TQTimer::timeout() signal is received by this slot. # sub timeout { my $new_time = TQt::Time::currentTime(); # get the current time _time = _time->addSecs(5); if($new_time->minute != _time->minute) { # minute has changed if(autoMask()) { updateMask(); } else { update(); } } } sub paintEvent { return if autoMask(); my $paint = TQt::Painter(this); $paint->setBrush(colorGroup()->foreground); drawClock($paint); } # If clock is transparent, we use updateMask() # instead of paintEvent() sub updateMask { # paint clock mask my $bm = TQt::Bitmap(size()); $bm->fill(&color0); # transparent my $paint = TQt::Painter; $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 centered square, as big as possible. The painter's pen and # brush colors are used. # sub drawClock { my $paint = shift; $paint->save; $paint->setWindow(-500,-500, 1000,1000); my $v = $paint->viewport; my $d = min($v->width, $v->height); $paint->setViewport($v->left + ($v->width-$d)/2, $v->top - ($v->height-$d)/2, $d, $d); # _time = TQt::Time::currentTime(); my $pts = TQt::PointArray(); $paint->save; $paint->rotate(30*(_time->hour%12-3) + _time->minute/2); $pts->setPoints([-20,0, 0,-20, 300,0, 0,20]); $paint->drawConvexPolygon($pts); $paint->restore; $paint->save; $paint->rotate((_time->minute-15)*6); $pts->setPoints([-10,0, 0,-10, 400,0, 0,10]); $paint->drawConvexPolygon($pts); $paint->restore; for(1 .. 12) { $paint->drawLine(440,0, 460,0); $paint->rotate(30); } $paint->restore; } sub setAutoMask { my $b = shift; setBackgroundMode($b ? &PaletteForeground : &PaletteBackground); TQt::Widget::setAutoMask($b); } 1;