Perl x Open Food Facts Hackathon: Paris, France - May 24-25 Learn more

#!/usr/bin/perl -w
#
# PerlQt Example Application: drawdemo
#
# Demonstrates the painter and the printer.
#
use QBrush;
use QColor;
use QFont;
use POSIX 'math_h'; # No atan() in Perl.
#
# This function draws a color wheel.
# The coordinate system x=(0..500), y=(0..500) spans the paint device.
#
sub drawColorWheel {
my $p = shift;
my $f = new QFont('Times', 18, $Weight{Bold});
$p->setFont($f);
$p->setPen($black);
$p->setWindow(0, 0, 500, 500);
for(my $i = 0; $i < 36; $i++) {
my $matrix = new QWMatrix;
$matrix->translate(250.0, 250.0);
$matrix->shear(0.0, 0.3);
$matrix->rotate($i*10);
$p->setWorldMatrix($matrix);
$c = new QColor;
$c->setHsv($i*10, 255, 255);
$p->setBrush($c);
$p->drawRect(70, -10, 80, 10);
$p->drawText(80+70+5, 0, "H=" . $i*10);
}
}
#
# This function draws a few lines of text using different fonts.
#
{
my @fonts = ('Helvetica', 'Courier', 'Times');
my @sizes = (10, 12, 18, 24);
sub drawFonts {
my $p = shift;
my($y) = (0, 0, 0);
for my $f (@fonts) {
for my $s (@sizes) {
my $font = new QFont($f, $s);
$p->setFont($font);
my $fm = $p->fontMetrics();
$y += $fm->ascent();
$p->drawText(10, $y, "Quartz Glyph Job Vex'd Cwm Finks");
$y += $fm->descent();
}
}
}
}
#
# This function draws some shapes
#
sub drawShapes {
my $p = shift;
my $b1 = new QBrush($blue);
my $b2 = new QBrush($green, $Brush{Dense6});
my $b3 = new QBrush($Brush{None});
my $b4 = new QBrush($Brush{Cross});
$p->setPen($red);
$p->setBrush($b1);
$p->drawRect(10, 10, 200, 100);
$p->setBrush($b2);
$p->drawRoundRect(10, 150, 200, 100, 20, 20);
$p->setBrush($b3);
$p->drawEllipse(250, 10, 200, 100);
$p->setBrush($b4);
$p->drawPie(250, 150, 200, 100, 45*16, 90*16);
}
#
# This function draws a text that follows a (Bezier) curve.
# Notice that this function does not support the general case.
# It should be rewritten to calculate the real dx/dy.
#
sub drawPathText {
my $p = shift;
my $a = new QPointArray(4);
$a->setPoint(0, 100,200);
$a->setPoint(1, 150,75);
$a->setPoint(2, 250,75);
$a->setPoint(3, 300,200);
$a = $a->quadBezier();
$p->setPen($lightGray);
$p->drawPolyline($a);
$p->setFont(new QFont('Times', 24));
$p->setPen($black);
my $text = "PerlQt rocks!";
my $len = length($text);
return unless $len;
my $ipos = 2; # $a->size()/$len; # ugly hack, fix me
my $cpos = $ipos;
for(my $i = 0; $i < $len; $i++) {
my $p1 = $a->point($cpos-1);
my $p2 = $a->point($cpos+1);
my $pt = $a->point($cpos);
my $dx = $p2->x() - $p1->x();
my $dy = $p2->y() - $p1->y();
my $angle = atan($dy/$dx);
$angle *= 180.0/3.14;
my $m = new QWMatrix;
$m->translate($pt->x(), $pt->y());
$m->rotate($angle);
$p->setWorldMatrix($m);
$p->drawText(0, 0, substr($text, $i, 1), 1);
$cpos += $ipos;
}
}
package DrawView;
use QColor;
use QWindow;
use slots 'updateIt(int)', 'printIt()';
@ISA = qw(QWindow);
@ourDrawFunctions = (
{ f => \&main::drawColorWheel, name => 'Draw color wheel' },
{ f => \&main::drawFonts, name => 'Draw fonts' },
{ f => \&main::drawShapes, name => 'Draw shapes' },
{ f => \&main::drawPathText, name => 'Draw path text' }
);
#
# Construct the DrawView with buttons.
#
sub new {
my $self = shift->SUPER::new;
$self->setCaption("PerlQt Draw Demo Application");
$self->setBackgroundColor($white);
my $printer = new QPrinter;
# Create a button group to contain all buttons
my $bgroup = new QButtonGroup($self);
$bgroup->resize(200, 200);
$self->connect($bgroup, 'clicked(int)', 'updateIt(int)');
# Calculate the size for the radio buttons
my $maxwidth = 80;
my $i;
my $n;
my $fm = $bgroup->fontMetrics();
for($i = 0; $i < @ourDrawFunctions; $i++) {#$i (0 .. $#ourDrawFunctions) {
$n = $ourDrawFunctions[$i]{'name'};
my $w = $fm->width($n);
$maxwidth = $w > $maxwidth ? $w : $maxwidth;
}
$maxwidth += 20;
for($i = 0; $i < @ourDrawFunctions; $i++) {
$n = $ourDrawFunctions[$i]{'name'};
my $rb = new QRadioButton($n, $bgroup)->immortal;
$rb->setGeometry(10, $i*30+10, $maxwidth, 30);
$rb->setChecked(1) if $i == 0;
}
my $drawindex = 0;
my $maxindex = $i;
$maxwidth += 40;
# Create and setup the print button
my $print = new QPushButton('Print', $bgroup);
$print->resize(80, 30);
$print->move($maxwidth/2 - $print->width()/2, $maxindex*30+20);
$self->connect($print, 'clicked()', 'printIt()');
$bgroup->resize($maxwidth, $print->y()+$print->height()+10);
$self->resize(640, 300);
@$self{'printer', 'bgroup', 'print', 'drawindex', 'maxindex'} =
($printer, $bgroup, $print, $drawindex, $maxindex);
return $self;
}
#
# Called when a radio button is clicked.
#
sub updateIt {
my $self = shift;
my $index = shift;
if($index < $$self{'maxindex'}) {
$$self{'drawindex'} = $index;
$self->update();
}
}
#
# Calls the drawing function as specified by the radio buttons.
#
sub drawIt {
my $self = shift;
my $p = shift;
my $drawindex = $$self{'drawindex'};
&{$ourDrawFunctions[$drawindex]{'f'}}($p);
}
#
# Called when the print button is clicked.
#
sub printIt {
my $self = shift;
my $printer = $$self{'printer'};
if($printer->setup($self)) {
my $paint = new QPainter;
$paint->begin($printer);
$self->drawIt($paint);
$paint->end();
}
}
sub paintEvent {
my $self = shift;
my $paint = new QPainter;
$paint->begin($self);
$self->drawIt($paint);
$paint->end();
}
#
# Called when the widget has been resized.
# Moves the button group to the upper right corner
# of the widget.
#
sub resizeEvent {
my $self = shift;
my $bgroup = $$self{'bgroup'};
$bgroup->move($self->width()-$bgroup->width(), 0);
}
package main;
use Qt;
$draw = new DrawView;
$qApp->setMainWidget($draw);
$draw->show();
exit $qApp->exec();