summaryrefslogtreecommitdiffstats
path: root/PerlQt/examples/aclock/AnalogClock.pm
blob: 0a52c4414d2a09ad80879a0ff62832ee6d6d2d6e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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;