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

« back to all changes in this revision

Viewing changes to src/Interaction/Interaction.h

  • 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
#ifndef MERKATOR_INTERACTION_H_
 
2
#define MERKATOR_INTERACTION_H_
 
3
 
 
4
class TrackPoint;
 
5
class MainWindow;
 
6
class Projection;
 
7
class TrackPoint;
 
8
class Way;
 
9
 
 
10
class QMouseEvent;
 
11
class QPaintEvent;
 
12
class QPainter;
 
13
 
 
14
#include "MainWindow.h"
 
15
#include "MapView.h"
 
16
#include "InfoDock.h"
 
17
#include "PropertiesDock.h"
 
18
#include "FeaturesDock.h"
 
19
#include "Maps/MapDocument.h"
 
20
#include "Maps/MapFeature.h"
 
21
#include "Maps/Road.h"
 
22
#include "Maps/TrackPoint.h"
 
23
 
 
24
#include <QtCore/QObject>
 
25
#include <QtCore/QTime>
 
26
#include <QtGui/QApplication>
 
27
#include <QtGui/QCursor>
 
28
#include <QtGui/QMouseEvent>
 
29
#include <QList>
 
30
 
 
31
#include <algorithm>
 
32
 
 
33
#define XY_TO_COORD(x)  projection().inverse(transform().inverted().map(QPointF(x)))
 
34
#define COORD_TO_XY(x)  transform().map(projection().project(x)).toPoint()
 
35
 
 
36
class Interaction : public QObject
 
37
{
 
38
        Q_OBJECT
 
39
        public:
 
40
                Interaction(MapView* theView);
 
41
                virtual ~Interaction();
 
42
 
 
43
                virtual void mousePressEvent(QMouseEvent * event);
 
44
                virtual void mouseReleaseEvent(QMouseEvent * event);
 
45
                virtual void mouseMoveEvent(QMouseEvent* event);
 
46
                virtual void paintEvent(QPaintEvent* anEvent, QPainter& thePainter);
 
47
                virtual QString toHtml() = 0;
 
48
 
 
49
#ifndef Q_OS_SYMBIAN
 
50
                virtual QCursor cursor() const;
 
51
#endif
 
52
                MapView* view();
 
53
                MapDocument* document();
 
54
                MainWindow* main();
 
55
                const Projection& projection() const;
 
56
                const QTransform& transform() const;
 
57
                bool panning() const;
 
58
        private:
 
59
                MapView* theView;
 
60
                bool Panning;
 
61
                QPoint FirstPan;
 
62
                QPoint LastPan;
 
63
        signals:
 
64
                void requestCustomContextMenu(const QPoint & pos);
 
65
 
 
66
        private:
 
67
                bool Dragging;
 
68
                Coord StartDrag;
 
69
                Coord EndDrag;
 
70
};
 
71
 
 
72
template<class FeatureType>
 
73
class GenericFeatureSnapInteraction : public Interaction
 
74
{
 
75
        public:
 
76
                GenericFeatureSnapInteraction(MapView* theView)
 
77
                        : Interaction(theView), LastSnap(0), SnapActive(true),
 
78
                          NoSelectPoints(false), NoSelectRoads(false)
 
79
                {
 
80
                }
 
81
 
 
82
                virtual void paintEvent(QPaintEvent* anEvent, QPainter& thePainter)
 
83
                {
 
84
                        Interaction::paintEvent(anEvent, thePainter);
 
85
 
 
86
                        for (int i=0; i<main()->features()->highlightedSize(); ++i)
 
87
                                if (document()->exists(main()->features()->highlighted(i)))
 
88
                                        main()->features()->highlighted(i)->drawHighlight(thePainter, view(), true);
 
89
                        for (int i=0; i<main()->properties()->size(); ++i)
 
90
                                if (document()->exists(main()->properties()->selection(i)))
 
91
                                        main()->properties()->selection(i)->drawFocus(thePainter, view());
 
92
                        for (int i=0; i<main()->properties()->highlightedSize(); ++i)
 
93
                                if (document()->exists(main()->properties()->highlighted(i)))
 
94
                                        main()->properties()->highlighted(i)->drawHighlight(thePainter, view(), true);
 
95
 
 
96
#ifndef _MOBILE
 
97
                        if (LastSnap && document()->exists(LastSnap)) {
 
98
                                LastSnap->drawHover(thePainter, view());
 
99
                                view()->setToolTip(LastSnap->toHtml());
 
100
                        } else {
 
101
                                view()->setToolTip("");
 
102
                        }
 
103
#endif
 
104
                }
 
105
                virtual void mousePressEvent(QMouseEvent * event)
 
106
                {
 
107
                        updateSnap(event);
 
108
                        snapMousePressEvent(event,LastSnap);
 
109
                        if (!(M_PREFS->getMouseSingleButton() && LastSnap))
 
110
                                Interaction::mousePressEvent(event);
 
111
                }
 
112
                virtual void mouseReleaseEvent(QMouseEvent * event)
 
113
                {
 
114
                        updateSnap(event);
 
115
                        snapMouseReleaseEvent(event,LastSnap);
 
116
                        if (!(M_PREFS->getMouseSingleButton() && LastSnap))
 
117
                                Interaction::mouseReleaseEvent(event);
 
118
                }
 
119
                virtual void mouseMoveEvent(QMouseEvent* event)
 
120
                {
 
121
                        updateSnap(event);
 
122
                        snapMouseMoveEvent(event, LastSnap);
 
123
                        if (!(M_PREFS->getMouseSingleButton() && LastSnap))
 
124
                                Interaction::mouseMoveEvent(event);
 
125
                }
 
126
                virtual void snapMousePressEvent(QMouseEvent * , FeatureType*)
 
127
                {
 
128
                }
 
129
                virtual void snapMouseReleaseEvent(QMouseEvent * , FeatureType*)
 
130
                {
 
131
                }
 
132
                virtual void snapMouseMoveEvent(QMouseEvent* , FeatureType*)
 
133
                {
 
134
                }
 
135
                void activateSnap(bool b)
 
136
                {
 
137
                        SnapActive = b;
 
138
                }
 
139
                void addToNoSnap(FeatureType* F)
 
140
                {
 
141
                        NoSnap.push_back(F);
 
142
                }
 
143
                void clearNoSnap()
 
144
                {
 
145
                        NoSnap.clear();
 
146
                }
 
147
                void clearSnap()
 
148
                {
 
149
                        StackSnap.clear();
 
150
                }
 
151
                void clearLastSnap()
 
152
                {
 
153
                        LastSnap = 0;
 
154
                }
 
155
                QList<MapFeature*> snapList()
 
156
                {
 
157
                        return StackSnap;
 
158
                }
 
159
                void addSnap(MapFeature* aSnap)
 
160
                {
 
161
                        StackSnap.append(aSnap);
 
162
                }
 
163
                void setSnap(QList<MapFeature*> aSnapList)
 
164
                {
 
165
                        StackSnap = aSnapList;
 
166
                        curStackSnap = 0;
 
167
                }
 
168
                void nextSnap()
 
169
                {
 
170
                        curStackSnap++;
 
171
                        if (curStackSnap > StackSnap.size() -1)
 
172
                                curStackSnap = 0;
 
173
                        view()->properties()->setSelection(StackSnap[curStackSnap]);
 
174
                        view()->update();
 
175
                }
 
176
                void previousSnap()
 
177
                {
 
178
                        curStackSnap--;
 
179
                        if (curStackSnap < 0)
 
180
                                curStackSnap = StackSnap.size() -1;
 
181
                        view()->properties()->setSelection(StackSnap[curStackSnap]);
 
182
                        view()->update();
 
183
                }
 
184
                void setDontSelectPoints(bool b)
 
185
                {
 
186
                        NoSelectPoints = b;
 
187
                }
 
188
                void setDontSelectRoads(bool b)
 
189
                {
 
190
                        NoSelectRoads = b;
 
191
                }
 
192
        private:
 
193
                void updateSnap(QMouseEvent* event)
 
194
                {
 
195
                        if (panning())
 
196
                        {
 
197
                                LastSnap = 0;
 
198
                                return;
 
199
                        }
 
200
                        bool NoRoads = 
 
201
                                ( (QApplication::keyboardModifiers() & Qt::AltModifier) &&  (QApplication::keyboardModifiers() &Qt::ControlModifier) );
 
202
                        FeatureType* Prev = LastSnap;
 
203
                        LastSnap = 0;
 
204
                        if (!SnapActive) return;
 
205
                        //QTime Start(QTime::currentTime());
 
206
                        CoordBox HotZone(XY_TO_COORD(event->pos()-QPointF(15,15)),XY_TO_COORD(event->pos()+QPointF(15,15)));
 
207
                        SnapList.clear();
 
208
                        double BestDistance = 5;
 
209
#if 1
 
210
                        //ggl::box < Coord > cb(HotZone.bottomLeft(), HotZone.topRight());
 
211
 
 
212
                        for (int j=0; j<document()->layerSize(); ++j) {
 
213
                                if (!document()->getLayer(j)->isVisible() || document()->getLayer(j)->isReadonly())
 
214
                                        continue;
 
215
 
 
216
                                std::deque < MapFeaturePtr > ret = document()->getLayer(j)->indexFind(HotZone);
 
217
                                for (std::deque < MapFeaturePtr >::const_iterator it = ret.begin(); it < ret.end(); ++it) {
 
218
                                        FeatureType* Pt = dynamic_cast<FeatureType*>(*it);
 
219
                                        if (Pt)
 
220
                                        {
 
221
                                                if (Pt->notEverythingDownloaded())
 
222
                                                        continue;
 
223
                                                if ( (NoRoads || NoSelectRoads) && dynamic_cast<Road*>(Pt))
 
224
                                                        continue;
 
225
                                                if (NoSelectPoints && dynamic_cast<TrackPoint*>(Pt))
 
226
                                                        continue;
 
227
                                                if (std::find(NoSnap.begin(),NoSnap.end(),Pt) != NoSnap.end())
 
228
                                                        continue;
 
229
                                                double Distance = Pt->pixelDistance(event->pos(), 5.01, projection(), transform());
 
230
                                                SnapList.push_back(Pt);
 
231
                                                if (Distance < BestDistance)
 
232
                                                {
 
233
                                                        BestDistance = Distance;
 
234
                                                        LastSnap = Pt;
 
235
                                                }
 
236
                                        }
 
237
                                }
 
238
                        }
 
239
 
 
240
#else
 
241
                        for (VisibleFeatureIterator it(document()); !it.isEnd(); ++it)
 
242
                        {
 
243
                                FeatureType* Pt = dynamic_cast<FeatureType*>(it.get());
 
244
                                if (Pt)
 
245
                                {
 
246
                                        if (Pt->layer()->isReadonly())
 
247
                                                continue;
 
248
                                        if (Pt->notEverythingDownloaded())
 
249
                                                continue;
 
250
                                        if ( (NoRoads || NoSelectRoads) && dynamic_cast<Road*>(Pt))
 
251
                                                continue;
 
252
                                        if (NoSelectPoints && dynamic_cast<TrackPoint*>(Pt))
 
253
                                                continue;
 
254
                                        if (std::find(NoSnap.begin(),NoSnap.end(),Pt) != NoSnap.end())
 
255
                                                continue;
 
256
                                        if (Pt->boundingBox().disjunctFrom(HotZone))
 
257
                                                continue;
 
258
                                        double Distance = Pt->pixelDistance(transform().inverted().map(event->pos()), 5.01, projection());
 
259
                                        SnapList.push_back(Pt);
 
260
                                        if (Distance < BestDistance)
 
261
                                        {
 
262
                                                BestDistance = Distance;
 
263
                                                LastSnap = Pt;
 
264
                                        }
 
265
                                }
 
266
                        }
 
267
#endif
 
268
                        if (Prev != LastSnap) {
 
269
                                curStackSnap = SnapList.indexOf(LastSnap);
 
270
                                view()->update();
 
271
                        }
 
272
 
 
273
                        if (M_PREFS->getMapTooltip()) {
 
274
                                if (LastSnap)
 
275
                                        view()->setToolTip(LastSnap->toHtml());
 
276
                                else
 
277
                                        view()->setToolTip("");
 
278
                        }
 
279
                        if (M_PREFS->getInfoOnHover() && main()->info()->isVisible()) {
 
280
                                if (LastSnap) {
 
281
                                        main()->info()->setHoverHtml(LastSnap->toHtml());
 
282
                                } else
 
283
                                        main()->info()->unsetHoverHtml();
 
284
                        }
 
285
                }
 
286
 
 
287
                FeatureType* LastSnap;
 
288
                QList<FeatureType*> NoSnap;
 
289
                bool SnapActive;
 
290
                bool NoSelectPoints;
 
291
                bool NoSelectWays;
 
292
                bool NoSelectRoads;
 
293
 
 
294
        protected:
 
295
                QList<MapFeature*> StackSnap;
 
296
                QList<MapFeature*> SnapList;
 
297
                int curStackSnap;
 
298
};
 
299
 
 
300
typedef GenericFeatureSnapInteraction<MapFeature> FeatureSnapInteraction;
 
301
typedef GenericFeatureSnapInteraction<TrackPoint> TrackPointSnapInteraction;
 
302
typedef GenericFeatureSnapInteraction<Road> RoadSnapInteraction;
 
303
 
 
304
#endif
 
305
 
 
306