#!/usr/bin/perl -w use Qt 2.0; $seed = 0.353535353535; $KINDA_RAND_MAX = 32767; sub kindaRand { $seed *= 147; $seed -= int($seed); return int($seed * ($KINDA_RAND_MAX + 1)); } sub velocity { my $i = shift; my $velmax = 10; my $velmin = 4; if($i == 1 || $i == 2) { $i = (kindaRand()&0x7fff % $velmax)/3 + $velmin; } else { $i = (kindaRand()&0x7fff % $velmax) + $velmin; } return $i; } # # Draw polygon on desktop. # sub poly { my $d = Qt::Application::desktop(); $d->setBackgroundColor(Qt::white); my $maxpoints = 5; my $maxcurves = 8; my @xvel; my @yvel; my $head = 0; my $tail = -$maxcurves + 2; my @a; my $p; my $r = $d->rect(); for(0..$maxcurves-1) { $a[$_] = Qt::PointArray->new; $a[$_]->resize($maxpoints); } $p = $a[0]; for(0..$maxpoints-1) { $p->setPoint($_, (kindaRand()&0x7fff) % $r->width(), (kindaRand()&0x7fff) % $r->height()); $xvel[$_] = velocity($_); $yvel[$_] = velocity($_); } my $paint = Qt::Painter->new; $paint->begin($d); for(my $ntimes = 0; $ntimes < 2000; $ntimes++) { $paint->setBrush(Qt::Color->new(kindaRand()%360, 180, 255, Qt::Color::Hsv)); $paint->drawPolygon($a[$head]); $tail = 0 if ++$tail >= $maxcurves; my($minx, $maxx) = ($r->left(), $r->right()); my($miny, $maxy) = ($r->top(), $r->bottom()); my($x, $y); $p = $a[$head]; $head = 0 if ++$head >= $maxcurves; for(0..$maxpoints-1) { $p->point($_, $x, $y); $x += $xvel[$_]; $y += $yvel[$_]; if($x > $maxx) { $x = $maxx - ($x - $maxx + 1); $xvel[$_] = -velocity($_); } if($x <= $minx) { $x = $minx + ($minx - $x + 1); $xvel[$_] = velocity($_); } if($y >= $maxy) { $y = $maxy - ($y - $maxy + 1); $yvel[$_] = -velocity($_); } if($y <= $miny) { $y = $miny + ($miny - $y + 1); $yvel[$_] = velocity($_); } $a[$head]->setPoint($_, $x, $y); } } $paint->end(); } # # Rotate pattern on desktop. # sub rotate { my $i; my $w = 64; my $h = 64; my $image = Qt::Image->new($w, $h, 8, 128); for($i = 0; $i < 128; $i++) { $image->setColor($i, Qt::Color::rgb($i,0,0)); } for(my $y = 0; $y < $h; $y++) { my $p = $image->scanLine($y); for(my $x = 0; $x < $w; $x++) { $$p[$x] = ($x+$y)%128; } } my $pm = Qt::Pixmap->new($image); $pm->optimize(1); my $d = Qt::Application::desktop(); for($i = 0; $i <= 360; $i += 2) { my $m = Qt::WMatrix->new; $m->rotate($i); my $rpm = $pm->xForm($m); $d->setBackgroundPixmap($rpm); $d->update(); } } # # Generates a marble-like pattern in pm. # sub generateStone { my $pm = shift; my($c1, $c2, $c3) = @_; my $p = Qt::Painter->new; my $p1 = Qt::Pen->new($c1); my $p2 = Qt::Pen->new($c2); my $p3 = Qt::Pen->new($c3); $p->begin($pm); my $width = $pm->width(); my $height = $pm->height(); my $r; my($i, $j); my $krmD3 = $KINDA_RAND_MAX / 3; my $krmD3T2 = $KINDA_RAND_MAX / 3 * 2; for($i = 0; $i < $width; $i++) { for($j = 0; $j < $height; $j++) { $r = kindaRand(); if($r < $krmD3) { $p->setPen($p1); } elsif($r < $krmD3T2) { $p->setPen($p2); } else { $p->setPen($p3); } $p->drawPoint($i, $j); } } $p->end(); } sub drawShadeText { my $p = shift; my $x = shift; my $y = shift; my $text = shift; my $topColor = shift; my $bottomColor = shift; my $sw = @_ ? shift : 2; return unless $p->isActive(); $p->setPen($bottomColor); $p->drawText($x+$sw, $y+$sw, $text); $p->setPen($topColor); $p->drawText($x, $y, $text); } package DesktopWidget; use Qt 2.0; @ISA = qw(Qt::Widget); sub new { my $s = shift; my $self = shift->SUPER::new(@_[0..1], Qt::WType_Desktop | Qt::WPaintDesktop); $self->{'text'} = $s; return $self; } sub paintEvent { my $c1 = $self->backgroundColor(); my $c2 = $c1->light(104); my $c3 = $c1->dark(106); unless(exists $self->{'pm'}) { my $pm = $self->{'pm'} = Qt::Pixmap->new(64, 64); generateStone($pm, $c1, $c2, $c3); $self->setBackgroundPixmap($pm); $self->update(); } my $br = $self->fontMetrics()->boundingRect($self->{'text'}); my $offscreen = Qt::Pixmap->new($br->width(), $br->height()); my $x = $self->width()/2 - $br->width()/2; my $y = $self->height()/2 - $br->height()/2; $offscreen->fill($self, $x, $y); my $p = Qt::Painter->new; $p->begin($offscreen); main::drawShadeText($p, -$br->x(), -$br->y(), $self->{'text'}, $c2, $c3, 3); $p->end(); $self->bitBlt($x, $y, $offscreen); } package main; import Qt::app; sub desktopWidget { my $t = DesktopWidget->new(@_); $t->update(); $app->exec(); } sub desktopText { my $s = @_ ? shift : 'PerlQt rocks'; my $border = 20; my $c1 = Qt::Application::palette()->normal()->background(); my $c2 = $c1->light(104); my $c3 = $c1->dark(106); my $pm = Qt::Pixmap->new(10, 10); my $p = Qt::Painter->new; $p->begin($pm); my $r = $p->fontMetrics()->boundingRect($s); $p->end(); my $appWidth = Qt::Application::desktop()->width(); my $appHeight = Qt::Application::desktop()->height(); if($r->width() > $appWidth - $border*2) { $r->setWidth($appWidth - $border*2); } if($r->height() > $appHeight - $border*2) { $r->setHeight($appHeight - $border*2); } $pm->resize($r->size() + Qt::Size->new($border*2, $border*2)); generateStone($pm, $c1, $c2, $c3); $p->begin($pm); drawShadeText($p, -$r->x() + $border, -$r->y() + $border, $s, $c2, $c3); $p->end(); Qt::Application::desktop()->setBackgroundPixmap($pm); } # # The program starts here. # use Qt 2.0; if(@ARGV) { my $f = Qt::Font->new('Charter', 96, Qt::Font::Black); $f->setStyleHint(Qt::Font::Times); Qt::Application::setFont($f); } $validOptions = 0; if(@ARGV == 1) { $validOptions = 1; if($ARGV[0] eq '-poly') { poly(); } elsif($ARGV[0] eq '-rotate') { rotate(); } elsif($ARGV[0] eq '-perlqt') { desktopText(); } elsif($ARGV[0] eq '-perlqtwidget') { desktopWidget(); } else { $validOptions = 0; } } elsif(@ARGV == 2) { $validOptions = 1; if($ARGV[0] eq '-shadetext') { desktopText($ARGV[1]); } elsif($ARGV[0] eq '-shadewidget') { desktopWidget($ARGV[1]); } else { $validOptions = 0; } } die < $0 -shadewidget CROAK