package SvgView;
use strict;
use warnings;
use Qt4;
use Qt4::isa qw( Qt4::GraphicsView );
use Qt4::slots
setHighQualityAntialiasing => ['bool'],
setViewBackground => ['bool'],
setViewOutline => ['bool'];
use constant {
Native => 0,
OpenGL => 1,
Image => 2
};
sub m_renderer() {
return this->{m_renderer};
}
sub m_svgItem() {
return this->{m_svgItem};
}
sub m_backgroundItem() {
return this->{m_backgroundItem};
}
sub m_outlineItem() {
return this->{m_outlineItem};
}
sub m_image() {
return this->{m_image};
}
sub NEW
{
my ($class, $parent) = @_;
if ( $parent ) {
$class->SUPER::NEW($parent);
}
else {
$class->SUPER::NEW();
}
this->{m_renderer} = Native;
this->{svgItem} = 0;
this->{backgroundItem} = 0;
this->{outlineItem} = 0;
this->{m_image} = Qt4::Image();
this->setScene(Qt4::GraphicsScene(this));
this->setTransformationAnchor(Qt4::GraphicsView::AnchorUnderMouse());
this->setDragMode(Qt4::GraphicsView::ScrollHandDrag());
# Prepare background check-board pattern
my $tilePixmap = Qt4::Pixmap(64, 64);
$tilePixmap->fill(Qt4::Color(Qt4::white()));
my $tilePainter = Qt4::Painter($tilePixmap);
my $color = Qt4::Color(220, 220, 220);
$tilePainter->fillRect(0, 0, 32, 32, Qt4::Brush($color));
$tilePainter->fillRect(32, 32, 32, 32, Qt4::Brush($color));
$tilePainter->end();
this->setBackgroundBrush(Qt4::Brush($tilePixmap));
}
sub drawBackground
{
my ($p) = @_;
$p->save();
$p->resetTransform();
$p->drawTiledPixmap(this->viewport()->rect(), this->backgroundBrush()->texture());
$p->restore();
}
sub openFile
{
my ($file) = @_;
if (!$file->exists()) {
return;
}
my $s = this->scene();
my $drawBackground = (this->m_backgroundItem ? this->m_backgroundItem->isVisible() : 0);
my $drawOutline = (this->m_outlineItem ? this->m_outlineItem->isVisible() : 1);
$s->clear();
this->resetTransform();
this->{m_svgItem} = Qt4::GraphicsSvgItem($file->fileName());
this->m_svgItem->setFlags(Qt4::GraphicsItem::ItemClipsToShape());
this->m_svgItem->setCacheMode(Qt4::GraphicsItem::NoCache());
this->m_svgItem->setZValue(0);
this->{m_backgroundItem} = Qt4::GraphicsRectItem(this->m_svgItem->boundingRect());
this->m_backgroundItem->setBrush(Qt4::Brush(Qt4::white()));
this->m_backgroundItem->setPen(Qt4::Pen(Qt4::NoPen()));
this->m_backgroundItem->setVisible($drawBackground);
this->m_backgroundItem->setZValue(-1);
this->{m_outlineItem} = Qt4::GraphicsRectItem(this->m_svgItem->boundingRect());
my $outline = Qt4::Pen(Qt4::Brush(Qt4::black()), 2, Qt4::DashLine());
$outline->setCosmetic(1);
this->m_outlineItem->setPen($outline);
# FIXME This should work with the 1 argument form. But that has been cached
# already as calling the QBrush(Qt4::GlobalColor) constructor.
this->m_outlineItem->setBrush(Qt4::Brush(Qt4::white(), Qt4::NoBrush()));
this->m_outlineItem->setVisible($drawOutline);
this->m_outlineItem->setZValue(1);
$s->addItem(this->m_backgroundItem);
$s->addItem(this->m_svgItem);
$s->addItem(this->m_outlineItem);
$s->setSceneRect(this->m_outlineItem->boundingRect()->adjusted(-10, -10, 10, 10));
}
sub setRenderer
{
my ($type) = @_;
this->{m_renderer} = $type;
if (this->m_renderer == OpenGL) {
#ifndef QT_NO_OPENGL
this->setViewport(Qt4::GLWidget(Qt4::GLFormat(Qt4::GL::SampleBuffers())));
#endif
} else {
this->setViewport(Qt4::Widget());
}
}
sub setHighQualityAntialiasing
{
my ($highQualityAntialiasing) = @_;
#ifndef QT_NO_OPENGL
this->setRenderHint(Qt4::Painter::HighQualityAntialiasing(), $highQualityAntialiasing);
#endif
}
sub setViewBackground
{
my ($enable) = @_;
if (!this->m_backgroundItem) {
return;
}
this->m_backgroundItem->setVisible($enable);
}
sub setViewOutline
{
my ($enable) = @_;
if (!this->m_outlineItem) {
return;
}
this->m_outlineItem->setVisible($enable);
}
sub paintEvent
{
my ($event) = @_;
if (this->m_renderer == Image) {
if (this->m_image->size() != this->viewport()->size()) {
this->{m_image} = Qt4::Image(this->viewport()->size(), Qt4::Image::Format_ARGB32_Premultiplied());
}
my $imagePainter = Qt4::Painter(this->m_image);
this->SUPER::render($imagePainter);
$imagePainter->end();
my $p = Qt4::Painter(this->viewport());
$p->drawImage(0, 0, this->m_image);
$p->end();
} else {
this->SUPER::paintEvent($event);
}
}
sub wheelEvent
{
my ($event) = @_;
my $factor = 1.2 ** ($event->delta() / 240.0);
this->scale($factor, $factor);
$event->accept();
}
1;