You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			138 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Raku
		
	
			
		
		
	
	
			138 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Raku
		
	
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;
 |