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;