/usr/local/CPAN/Qt/DiagramScene.pm
package DiagramScene;
use strict;
use warnings;
use QtCore4;
use QtGui4;
use DiagramItem;
use DiagramTextItem;
use Arrow;
# [0]
use QtCore4::isa qw( Qt::GraphicsScene );
use QtCore4::slots
setMode => ['int'],
setItemType => ['int'],
editorLostFocus => ['QGraphicsTextItem *'];
use QtCore4::signals
itemInserted => ['QGraphicsPolygonItem *'],
textInserted => ['QGraphicsTextItem *'],
itemSelected => ['QGraphicsItem *'];
use constant {
InsertItem => 0,
InsertLine => 1,
InsertText => 2,
MoveItem => 3,
};
sub font()
{ return this->{myFont}; }
sub textColor()
{ return this->{myTextColor}; }
sub itemColor()
{ return this->{myItemColor}; }
sub lineColor()
{ return this->{myLineColor}; }
sub myItemType() {
return this->{myItemType};
}
sub myItemMenu() {
return this->{myItemMenu};
}
sub myMode() {
return this->{myMode};
}
sub leftButtonDown() {
return this->{leftButtonDown};
}
sub startPoint() {
return this->{startPoint};
}
sub line() {
return this->{line};
}
sub textItem() {
return this->{textItem};
}
# [0]
sub NEW
{
my ($class, $itemMenu, $parent) = @_;
$class->SUPER::NEW($parent);
this->{myItemMenu} = $itemMenu;
this->{myMode} = MoveItem;
this->{myItemType} = DiagramItem::Step;
this->{line} = undef;
this->{textItem} = DiagramTextItem();
this->{myItemColor} = Qt::white();
this->{myTextColor} = Qt::black();
this->{myLineColor} = Qt::black();
this->{myFont} = Qt::Font();
}
# [0]
# [1]
sub setLineColor
{
my ($color) = @_;
this->{myLineColor} = $color;
if (this->isItemChange(Arrow::Type)) {
my $item = this->selectedItems()->[0];
$item->setColor(this->lineColor);
this->update();
}
}
# [1]
# [2]
sub setTextColor
{
my ($color) = @_;
this->{myTextColor} = $color;
if (this->isItemChange(DiagramTextItem::Type)) {
my $item = this->selectedItems()->[0];
$item->setDefaultTextColor(this->textColor);
}
}
# [2]
# [3]
sub setItemColor
{
my ($color) = @_;
this->{myItemColor} = $color;
if (this->isItemChange(DiagramItem::Type)) {
my $item = this->selectedItems()->[0];
$item->setBrush(Qt::Brush(this->itemColor));
}
}
# [3]
# [4]
sub setFont
{
my ($font) = @_;
this->{myFont} = $font;
if (this->isItemChange(DiagramTextItem::Type)) {
my $item = this->selectedItems()->[0];
# At this point the selection can change so the first selected item might not be a DiagramTextItem
if (ref $item eq ' DiagramTextItem') {
$item->setFont(this->font);
}
}
}
# [4]
sub setMode
{
my ($mode) = @_;
this->{myMode} = $mode;
}
sub setItemType
{
my ($type) = @_;
this->{myItemType} = $type;
}
# [5]
sub editorLostFocus
{
my ($item) = @_;
my $cursor = $item->textCursor();
$cursor->clearSelection();
$item->setTextCursor($cursor);
if (!$item->toPlainText()) {
this->removeItem($item);
$item->deleteLater();
}
}
# [5]
# [6]
sub mousePressEvent
{
my ($mouseEvent) = @_;
if ($mouseEvent->button() != Qt::LeftButton()) {
return;
}
if ( this->myMode == InsertItem ) {
my $item = DiagramItem(this->myItemType, this->myItemMenu);
$item->setBrush(Qt::Brush(this->itemColor));
this->addItem($item);
$item->setPos($mouseEvent->scenePos());
emit this->itemInserted($item);
# [6] //! [7]
}
elsif ( this->myMode == InsertLine ) {
this->{line} = Qt::GraphicsLineItem(Qt::LineF($mouseEvent->scenePos(),
$mouseEvent->scenePos()));
this->line->setPen(Qt::Pen(Qt::Brush(this->{myLineColor}), 2));
this->addItem(this->line);
# [7] //! [8]
}
elsif ( this->myMode == InsertText ) {
this->{textItem} = DiagramTextItem();
this->textItem->setFont(this->font);
this->textItem->setTextInteractionFlags(Qt::TextEditorInteraction());
this->textItem->setZValue(1000.0);
this->connect(this->textItem, SIGNAL 'lostFocus(QGraphicsTextItem*)',
this, SLOT 'editorLostFocus(QGraphicsTextItem*)');
this->connect(this->textItem, SIGNAL 'selectedChange(QGraphicsItem*)',
this, SIGNAL 'itemSelected(QGraphicsItem*)');
this->addItem(this->textItem);
this->textItem->setDefaultTextColor(Qt::Color(this->textColor));
this->textItem->setPos($mouseEvent->scenePos());
emit this->textInserted(this->textItem);
}
# [8] //! [9]
this->SUPER::mousePressEvent($mouseEvent);
}
# [9]
# [10]
sub mouseMoveEvent
{
my ($mouseEvent) = @_;
if (this->myMode == InsertLine && defined line) {
my $newLine = Qt::LineF(this->line->line()->p1(), $mouseEvent->scenePos());
this->line->setLine($newLine);
} elsif (this->myMode == MoveItem) {
this->SUPER::mouseMoveEvent($mouseEvent);
}
}
# [10]
# [11]
sub mouseReleaseEvent
{
my ($mouseEvent) = @_;
if (defined this->line && this->myMode == InsertLine) {
my $startItems = this->items(this->line->line()->p1());
if (scalar @{$startItems} && $startItems->[0] eq this->line) {
shift @{$startItems};
}
my $endItems = this->items(this->line->line()->p2());
if (scalar @{$endItems} && $endItems->[0] eq this->line) {
shift @{$endItems};
}
this->removeItem(this->line);
# [11] //! [12]
if (scalar @{$startItems} > 0 && scalar @{$endItems} > 0 &&
$startItems->[0]->type() == DiagramItem::Type &&
$endItems->[0]->type() == DiagramItem::Type &&
$startItems->[0] != $endItems->[0]) {
my $startItem = $startItems->[0];
my $endItem = $endItems->[0];
my $arrow = Arrow($startItem, $endItem);
$arrow->setColor(this->lineColor);
$startItem->addArrow($arrow);
$endItem->addArrow($arrow);
$arrow->setZValue(-1000.0);
this->addItem($arrow);
$arrow->updatePosition();
}
}
# [12] //! [13]
this->{line} = undef;
this->SUPER::mouseReleaseEvent($mouseEvent);
}
# [13]
# [14]
sub isItemChange
{
my ($type) = @_;
foreach my $item ( @{this->selectedItems()} ) {
if ($item->type() == $type) {
return 1;
}
}
return 0;
}
# [14]
1;