Root/Software/sie_cg/block_editor/arrow.cpp

1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtGui>
43
44#include "arrow.h"
45#include "lineitem.h"
46#include <math.h>
47
48const qreal Pi = 3.14;
49
50Arrow::Arrow( QPointF startP,QPointF endP,
51              QGraphicsItem *parent, QGraphicsScene *scene)
52    : QGraphicsPathItem(parent, scene)
53{
54    startPoint=startP;
55    endPoint=endP;
56    arrowSize = 10;
57    moving=0;
58    //setFlag(QGraphicsItem::ItemIsMovable, true);
59    setFlag(QGraphicsItem::ItemIsSelectable, true);
60    myColor = Qt::black;
61    setPen(QPen(myColor, 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
62    //setZValue(0.0);
63    myOwnerScene = scene;
64    lineItem *newLine= new lineItem(QPointF(0,0),QPointF(0,0),this);
65    myOwnerScene->addItem(newLine);
66    addLine(newLine);
67
68    updatePosition();
69}
70
71void Arrow::removeLine(lineItem *line)
72{
73    int index = myLines.indexOf(line);
74
75    if (index != -1){
76        //Adjust the corners
77        if(myLines.count()>1)
78        {
79            if(index==0)
80            {
81                myCorners.removeAt(0);
82                myOwnerScene->removeItem(myCLines.at(0));
83                myCLines.removeAt(0);
84            }
85            else if(index>0)
86            {
87                myCorners.removeAt(index-1);
88                myOwnerScene->removeItem(myCLines.at(index-1));
89                myCLines.removeAt(index-1);
90            }
91        }
92        myLines.removeAt(index);
93    }
94
95    //If lines is empty the arrow is removed
96    if (myLines.count()<3)
97    {
98        removeLines();
99        myOwnerScene->removeItem(this);
100    }
101}
102
103void Arrow::removeLines()
104{
105    foreach (lineItem *line, myLines) {
106        scene()->removeItem(line);
107        delete line;
108    }
109    foreach (lineItem *line, myCLines) {
110        scene()->removeItem(line);
111        delete line;
112    }
113    if(myOwnerScene->items().indexOf(SECLine)!=-1)
114    {
115        scene()->removeItem(SECLine);
116        delete SECLine;
117    }
118}
119
120bool Arrow::addLine(lineItem *line)
121{
122        myLines.append(line);
123        return 1;
124}
125
126QRectF Arrow::boundingRect() const
127{
128    qreal extra = (pen().width() + arrowSize*2) / 2.0;
129
130    return QGraphicsPathItem::boundingRect()
131           .normalized()
132           .adjusted(-extra, -extra, extra, extra);
133}
134
135QPainterPath Arrow::shape() const
136{
137    QPainterPath path = QGraphicsPathItem::shape();
138    return path;
139}
140
141void Arrow::updatePosition()
142{
143    QPainterPath myPath;
144    myPath.moveTo(startPoint);
145    if(!myCorners.isEmpty())
146        foreach(QPointF corner, myCorners){
147            myPath.lineTo(corner);
148        }
149    myPath.lineTo(endPoint);
150
151    setPath(myPath);
152}
153
154void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
155          QWidget *)
156{
157    //Update line positions
158    QPen myPen = pen();
159    myPen.setColor(myColor);
160    painter->setPen(myPen);
161    painter->setBrush(myColor);
162
163    QPointF endPos=endPoint;
164    QPointF startPos=startPoint;
165
166    if(myCorners.isEmpty())
167    {
168        myLines.first()->setLine(QLineF(startPos,endPos));
169    }
170    else
171    {
172        myLines.first()->setLine(QLineF(startPos,myCorners.first()));
173        for(int i=0; i<myCorners.count()-1;i++)
174          myLines.at(i+1)->setLine(QLineF(myCorners.at(i),myCorners.at(i+1)));
175        myLines.last()->setLine(QLineF(myCorners.last(),endPos));
176    }
177
178    //Drawing arrow selected
179    for(int i=0; i<myLines.count();i++)
180    {
181        if (isSelected())
182        {
183            painter->setPen(QPen(Qt::gray, 2, Qt::SolidLine));
184            QLineF myLine = myLines.at(i)->line();
185            painter->drawLine(myLine);
186            foreach (lineItem *line, myLines) { line->setColor(Qt::gray);}
187            foreach (lineItem *line, myCLines) { line->setColor(Qt::gray);}
188            if(myOwnerScene->items().indexOf(SECLine)!=-1)
189                SECLine->setColor(Qt::gray);
190        }
191        else
192        {
193            foreach (lineItem *line, myLines) { line->setColor(myColor);}
194            foreach (lineItem *line, myCLines) { line->setColor(myColor);}
195            if(myOwnerScene->items().indexOf(SECLine)!=-1)
196                SECLine->setColor(myColor);
197        }
198    }
199    painter->setBrush(Qt::lightGray);
200    painter->drawPolygon(this->path().toFillPolygon());
201    setSelectedArrows();
202}
203
204void Arrow::setSelectedArrows()
205{
206    bool anySelected = 0;
207
208    foreach(lineItem *line,myLines){ if(line->isSelected())anySelected=1;}
209    foreach(lineItem *line,myCLines){ if(line->isSelected())anySelected=1;}
210    if(isSelected()) anySelected=1;
211
212    if(anySelected)
213        setVisibleCorners(1);
214    else
215        setVisibleCorners(0);
216}
217
218void Arrow::createCorner(QPointF cornerPos, lineItem *inLine)
219{
220    createCorner(cornerPos,myLines.indexOf(inLine));
221}
222
223void Arrow::createCorner(QPointF cornerPos, int index)
224{
225    if (index != -1)
226    {
227            myCorners.insert(index,cornerPos);
228            lineItem *newLine= new lineItem(cornerPos,cornerPos,this);
229            myOwnerScene->addItem(newLine);
230            newLine->setZValue(this->zValue());
231            addLine(newLine);
232            newLine= new lineItem(cornerPos+QPointF(-0.5,-0.5) ,
233                                  cornerPos+QPointF(0.5,0.5),this,6,1);
234            myOwnerScene->addItem(newLine);
235            newLine->setZValue(this->zValue()+0.1);
236            myCLines.insert(index,newLine);
237    }
238    updatePosition();
239}
240void Arrow::createFirstCorner()
241{
242    if(myOwnerScene->items().indexOf(SECLine)==-1)
243    {
244        SECLine = new lineItem(startPoint+QPointF(-0.5,-0.5) ,
245                               startPoint+QPointF(0.5,0.5),this,6,1);
246        myOwnerScene->addItem(SECLine);
247        SECLine->setVisible(1);
248        SECLine->setZValue(this->zValue()+0.1);
249    }
250    updatePosition();
251}
252
253void Arrow::moveCorner(QPointF cornerPos, lineItem *inLine, bool relative)
254{
255    int index = myCLines.indexOf(inLine);
256    if(relative) cornerPos=mapFromItem(inLine,cornerPos);
257
258    if (index != -1)
259    {
260        myCorners.replace(index,cornerPos);
261    }
262    else if (inLine == SECLine)
263    {
264        startPoint=cornerPos;
265        endPoint=cornerPos;
266    }
267    updatePosition();
268}
269
270void Arrow::setVisibleCorners(bool visible)
271{
272    foreach (lineItem *line, myCLines) {
273        line->setVisible(visible);
274        line->setZValue(2000.0);
275    }
276    if(myOwnerScene->items().indexOf(SECLine)!=-1)
277    {
278        SECLine->setVisible(1);
279    }
280    updatePosition();
281}
282
283void Arrow::snapToGrid(QGraphicsSceneMouseEvent *event)
284{
285    //TODO implement polygon drag
286    QPointF diffPos= event->scenePos()-previousPos;
287    printf("diff[%f|%f]\n",diffPos.x(),diffPos.y()); fflush(stdout);
288    //Update corners:
289    for(int i=0; i < myCorners.count();i++)
290    {
291        myCLines.at(i)->setLine(QLineF(myCLines.at(i)->line().p1()+diffPos,
292                                       myCLines.at(i)->line().p2()+diffPos));
293        QPointF itemPos = myCLines.at(i)->line().p1()+QPointF(0.5,0.5);
294        moveCorner(itemPos,myCLines.at(i));
295    }
296    if(myOwnerScene->items().indexOf(SECLine)!=-1)
297    {
298        SECLine->setLine(QLineF(SECLine->line().p1()+diffPos,
299                                 SECLine->line().p2()+diffPos));
300        QPointF itemPos = SECLine->line().p1()+QPointF(0.5,0.5);
301        moveCorner(itemPos,SECLine);
302    }
303    updatePosition();
304}
305
306void Arrow::mousePressEvent(QGraphicsSceneMouseEvent *event)
307{
308    //if(this->isSelected())
309    {
310        previousPos = event->scenePos();
311        moving=1;
312    }
313    QGraphicsPathItem::mousePressEvent(event);
314}
315
316void Arrow::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
317{
318    if(moving && isSelected())
319    {
320        snapToGrid(event);
321        previousPos = event->scenePos();
322    }
323    moving=0;
324    QGraphicsPathItem::mouseReleaseEvent(event);
325}
326
327void Arrow::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
328{
329    if(moving && isSelected())
330    {
331        snapToGrid(event);
332        previousPos = event->scenePos();
333    }
334    QGraphicsPathItem::mouseMoveEvent(event);
335}
336
337QDomElement Arrow::toXml(QDomDocument &document) const
338{
339        QDomElement diagramArrow = document.createElement("Polygon");
340        //Point list
341        if(!myCorners.isEmpty())
342        {
343            QDomElement arrowCorner;
344            //start point
345            arrowCorner = document.createElement("Point");
346            arrowCorner.setAttribute("x",(startPoint-QPointF(500,500)).x());
347            arrowCorner.setAttribute("y",(startPoint-QPointF(500,500)).y());
348            diagramArrow.appendChild(arrowCorner);
349            //corner points
350            foreach(QPointF corner, myCorners)
351            {
352                arrowCorner = document.createElement("Point");
353                arrowCorner.setAttribute("x",(corner-QPointF(500,500)).x());
354                arrowCorner.setAttribute("y",(corner-QPointF(500,500)).y());
355                diagramArrow.appendChild(arrowCorner);
356            }
357        }
358        return (diagramArrow);
359}
360

Archive Download this file

Branches:
master



interactive