~ubuntu-branches/ubuntu/saucy/merkaartor/saucy

« back to all changes in this revision

Viewing changes to src/Interaction/CreatePolygonInteraction.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Bernd Zeimetz
  • Date: 2009-09-13 00:52:12 UTC
  • mto: (1.2.7 upstream) (0.1.3 upstream) (3.1.7 sid)
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20090913005212-pjecal8zxm07x0fj
ImportĀ upstreamĀ versionĀ 0.14+svnfixes~20090912

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "Interaction/CreatePolygonInteraction.h"
 
2
#include "Command/DocumentCommands.h"
 
3
#include "Command/RoadCommands.h"
 
4
#include "Command/TrackPointCommands.h"
 
5
#include "Maps/Painting.h"
 
6
#include "Maps/Road.h"
 
7
#include "Maps/TrackPoint.h"
 
8
#include "Utils/LineF.h"
 
9
#include "PropertiesDock.h"
 
10
#include "Preferences/MerkaartorPreferences.h"
 
11
 
 
12
#include <QtGui/QPainter>
 
13
#include <QInputDialog>
 
14
 
 
15
#include <math.h>
 
16
 
 
17
CreatePolygonInteraction::CreatePolygonInteraction(MainWindow* aMain, MapView* aView, int sides)
 
18
        : Interaction(aView), Main(aMain), Origin(0,0), Sides(sides), HaveOrigin(false), bAngle(0.0), bScale(QPointF(1., 1.))
 
19
{
 
20
}
 
21
 
 
22
CreatePolygonInteraction::~CreatePolygonInteraction()
 
23
{
 
24
        view()->update();
 
25
}
 
26
 
 
27
QString CreatePolygonInteraction::toHtml()
 
28
{
 
29
        QString help;
 
30
        help = (MainWindow::tr("LEFT-CLICK to start;DRAG to scale;SHIFT-DRAG to rotate;LEFT-CLICK to end"));
 
31
 
 
32
        QStringList helpList = help.split(";");
 
33
 
 
34
        QString desc;
 
35
        desc = QString("<big><b>%1</b></big>").arg(MainWindow::tr("Create Polygon Interaction"));
 
36
 
 
37
        QString S =
 
38
        "<html><head/><body>"
 
39
        "<small><i>" + QString(metaObject()->className()) + "</i></small><br/>"
 
40
        + desc;
 
41
        S += "<hr/>";
 
42
        S += "<ul style=\"margin-left: 0px; padding-left: 0px;\">";
 
43
        for (int i=0; i<helpList.size(); ++i) {
 
44
                S+= "<li>" + helpList[i] + "</li>";
 
45
        }
 
46
        S += "</ul>";
 
47
        S += "</body></html>";
 
48
 
 
49
        return S;
 
50
}
 
51
 
 
52
 
 
53
void CreatePolygonInteraction::testIntersections(CommandList* L, Road* Left, int FromIdx, Road* Right, int RightIndex)
 
54
{
 
55
        LineF L1(COORD_TO_XY(Right->getNode(RightIndex-1)),
 
56
                COORD_TO_XY(Right->getNode(RightIndex)));
 
57
        for (int i=FromIdx; i<Left->size(); ++i)
 
58
        {
 
59
                LineF L2(COORD_TO_XY(Left->getNode(i-1)),
 
60
                        COORD_TO_XY(Left->getNode(i)));
 
61
                QPointF Intersection(L1.intersectionWith(L2));
 
62
                if (L1.segmentContains(Intersection) && L2.segmentContains(Intersection))
 
63
                {
 
64
                        TrackPoint* Pt = new TrackPoint(XY_TO_COORD(Intersection));
 
65
                        L->add(new AddFeatureCommand(Main->document()->getDirtyOrOriginLayer(),Pt,true));
 
66
                        L->add(new RoadAddTrackPointCommand(Left,Pt,i));
 
67
                        L->add(new RoadAddTrackPointCommand(Right,Pt,RightIndex));
 
68
                        testIntersections(L,Left,i+2,Right,RightIndex);
 
69
                        testIntersections(L,Left,i+2,Right,RightIndex+1);
 
70
                        return;
 
71
                }
 
72
        }
 
73
}
 
74
 
 
75
void CreatePolygonInteraction::mousePressEvent(QMouseEvent * event)
 
76
{
 
77
        if (event->buttons() & Qt::LeftButton)
 
78
        {
 
79
                if (!HaveOrigin)
 
80
                {
 
81
                        HaveOrigin = true;
 
82
                        Origin = XY_TO_COORD(event->pos());
 
83
                        OriginF = event->pos();
 
84
                        bAngle = 0.;
 
85
                        bScale = QPointF(1., 1.);
 
86
                }
 
87
                else
 
88
                {
 
89
                        QPointF CenterF(0.5, 0.5);
 
90
                        double Radius = 0.5;
 
91
                        if (Sides == 4)
 
92
                                Radius = sqrt(2.)/2.;
 
93
                        double Angle = 2*M_PI/Sides;
 
94
                        QBrush SomeBrush(QColor(0xff,0x77,0x11,128));
 
95
                        QPen TP(SomeBrush,view()->pixelPerM()*4);
 
96
 
 
97
                        QMatrix m;
 
98
                        m.translate(OriginF.x(), OriginF.y());
 
99
                        m.rotate(bAngle);
 
100
                        m.scale(bScale.x(), bScale.y());
 
101
 
 
102
                        QPointF Prev(CenterF.x()+cos(-Angle/2)*Radius,CenterF.y()+sin(-Angle/2)*Radius);
 
103
                        TrackPoint* First = new TrackPoint(XY_TO_COORD(m.map(Prev)));
 
104
                        Road* R = new Road;
 
105
                        R->add(First);
 
106
                        if (M_PREFS->apiVersionNum() < 0.6)
 
107
                                R->setTag("created_by", QString("Merkaartor v%1%2").arg(STRINGIFY(VERSION)).arg(STRINGIFY(REVISION)));
 
108
                        CommandList* L  = new CommandList(MainWindow::tr("Create Polygon %1").arg(R->id()), R);
 
109
                        L->add(new AddFeatureCommand(Main->document()->getDirtyOrOriginLayer(),First,true));
 
110
                        for (double a = 2*M_PI - Angle*3/2; a>0; a-=Angle)
 
111
                        {
 
112
                                QPointF Next(CenterF.x()+cos(a)*Radius,CenterF.y()+sin(a)*Radius);
 
113
                                TrackPoint* New = new TrackPoint(XY_TO_COORD(m.map(Next)));
 
114
                                if (M_PREFS->apiVersionNum() < 0.6)
 
115
                                        New->setTag("created_by", QString("Merkaartor v%1%2").arg(STRINGIFY(VERSION)).arg(STRINGIFY(REVISION)));
 
116
                                L->add(new AddFeatureCommand(Main->document()->getDirtyOrOriginLayer(),New,true));
 
117
                                R->add(New);
 
118
                        }
 
119
                        R->add(First);
 
120
                        L->add(new AddFeatureCommand(Main->document()->getDirtyOrOriginLayer(),R,true));
 
121
                        for (FeatureIterator it(document()); !it.isEnd(); ++it)
 
122
                        {
 
123
                                Road* W1 = dynamic_cast<Road*>(it.get());
 
124
                                if (W1 && (W1 != R))
 
125
                                        for (int i=1; i<W1->size(); ++i)
 
126
                                        {
 
127
                                                int Before = W1->size();
 
128
                                                testIntersections(L,R,1,W1,i);
 
129
                                                int After = W1->size();
 
130
                                                i += (After-Before);
 
131
                                        }
 
132
                        }
 
133
                        Main->properties()->setSelection(R);
 
134
                        document()->addHistory(L);
 
135
                        view()->invalidate(true, false);
 
136
                        view()->launch(0);
 
137
                }
 
138
        }
 
139
        else
 
140
                Interaction::mousePressEvent(event);
 
141
}
 
142
 
 
143
void CreatePolygonInteraction::paintEvent(QPaintEvent* , QPainter& thePainter)
 
144
{
 
145
        if (HaveOrigin)
 
146
        {
 
147
                QPointF CenterF(0.5, 0.5);
 
148
                double Radius = 0.5;
 
149
                if (Sides == 4)
 
150
                        Radius = sqrt(2.)/2.;
 
151
 
 
152
                QMatrix m;
 
153
                m.translate(OriginF.x(), OriginF.y());
 
154
                m.rotate(bAngle);
 
155
                m.scale(bScale.x(), bScale.y());
 
156
                QPolygonF thePoly = m.map(QRectF(QPointF(0.0, 0.0), QPointF(1.0, 1.0)));
 
157
 
 
158
                thePainter.setPen(QPen(QColor(0,0,255),1,Qt::DotLine));
 
159
                thePainter.drawPolygon(thePoly);
 
160
 
 
161
                double Angle = 2*M_PI/Sides;
 
162
                QBrush SomeBrush(QColor(0xff,0x77,0x11,128));
 
163
                QPen TP(SomeBrush,view()->pixelPerM()*4);
 
164
                QPointF Prev(CenterF.x()+cos(-Angle/2)*Radius,CenterF.y()+sin(-Angle/2)*Radius);
 
165
                for (double a = 2*M_PI - Angle*3/2; a>0; a-=Angle)
 
166
                {
 
167
                        QPointF Next(CenterF.x()+cos(a)*Radius,CenterF.y()+sin(a)*Radius);
 
168
                        ::draw(thePainter,TP,MapFeature::UnknownDirection, m.map(Prev),m.map(Next),4,view()->projection());
 
169
                        Prev = Next;
 
170
                }
 
171
                QPointF Next(CenterF.x()+cos(-Angle/2)*Radius,CenterF.y()+sin(-Angle/2)*Radius);
 
172
                ::draw(thePainter,TP,MapFeature::UnknownDirection, m.map(Prev),m.map(Next),4,view()->projection());
 
173
        }
 
174
}
 
175
 
 
176
void CreatePolygonInteraction::mouseMoveEvent(QMouseEvent* event)
 
177
{
 
178
        if (HaveOrigin) {
 
179
                QMatrix m;
 
180
                m.translate(OriginF.x(), OriginF.y());
 
181
                m.rotate(bAngle);
 
182
 
 
183
                if (event->modifiers() & Qt::ShiftModifier) {
 
184
                        bAngle += radToAng(angle(m.inverted().map(LastCursor), m.inverted().map(event->pos())));
 
185
 
 
186
                        QMatrix m2;
 
187
                        m2.translate(OriginF.x(), OriginF.y());
 
188
                        m2.rotate(bAngle);
 
189
                        bScale = m2.inverted().map(event->pos());
 
190
                } else {
 
191
                        bScale = m.inverted().map(event->pos());
 
192
                }
 
193
 
 
194
                view()->update();
 
195
        }
 
196
        LastCursor = event->pos();
 
197
        Interaction::mouseMoveEvent(event);
 
198
}
 
199
 
 
200
 
 
201
#ifndef Q_OS_SYMBIAN
 
202
QCursor CreatePolygonInteraction::cursor() const
 
203
{
 
204
        return QCursor(Qt::CrossCursor);
 
205
}
 
206
#endif