1 |
|
---|
2 | #include <QGraphicsScene>
|
---|
3 | #include <QGraphicsTextItem>
|
---|
4 | #include <QTextStream>
|
---|
5 | #include <QScrollBar>
|
---|
6 | #include <QMouseEvent>
|
---|
7 | #include <QWheelEvent>
|
---|
8 | #include <QDebug>
|
---|
9 | #include <iostream>
|
---|
10 |
|
---|
11 | #include "bncmapview.h"
|
---|
12 |
|
---|
13 |
|
---|
14 | // -------------
|
---|
15 | BncMapView::BncMapView(QWidget* parent) : QGraphicsView(parent)
|
---|
16 | {
|
---|
17 | setCursor(Qt::OpenHandCursor);
|
---|
18 | setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
---|
19 | }
|
---|
20 |
|
---|
21 | /* -------------
|
---|
22 | * Sets the current centerpoint. Also updates the scene's center point.
|
---|
23 | * Unlike centerOn, which has no way of getting the floating point center
|
---|
24 | * back, SetCenter() stores the center point. It also handles the special
|
---|
25 | * sidebar case. This function will claim the centerPoint to sceneRec ie.
|
---|
26 | * the centerPoint must be within the sceneRec.
|
---|
27 | */
|
---|
28 | void BncMapView::SetCenter(const QPointF& centerPoint)
|
---|
29 | {
|
---|
30 | // get the rectangle of the visible area in scene coords
|
---|
31 | QRectF visibleArea = mapToScene(rect()).boundingRect();
|
---|
32 |
|
---|
33 | // get the scene area
|
---|
34 | QRectF sceneBounds = sceneRect();
|
---|
35 |
|
---|
36 | double boundX = + visibleArea.width() / 2.0;
|
---|
37 | double boundY = - visibleArea.height() / 2.0; // opposite sign for latitude !
|
---|
38 |
|
---|
39 | double boundWidth = sceneBounds.width() - boundX * 2.0;
|
---|
40 | double boundHeight = sceneBounds.height() - boundY * 2.0;
|
---|
41 |
|
---|
42 | // the max boundary that the centerPoint can be to
|
---|
43 | QRectF bounds(boundX, boundY, boundWidth, boundHeight);
|
---|
44 |
|
---|
45 | if( bounds.contains(centerPoint) ){
|
---|
46 | // we are within the bounds
|
---|
47 | _currentCenterPoint = centerPoint;
|
---|
48 |
|
---|
49 | }else{
|
---|
50 |
|
---|
51 | // we need to clamp or use the center of the screen
|
---|
52 | if( visibleArea.contains(sceneBounds) ){
|
---|
53 |
|
---|
54 | // use the center of scene ie. we can see the whole scene
|
---|
55 | _currentCenterPoint = sceneBounds.center();
|
---|
56 |
|
---|
57 | }else{
|
---|
58 | _currentCenterPoint = centerPoint;
|
---|
59 |
|
---|
60 | // we need to clamp the center. The centerPoint is too large
|
---|
61 | if( centerPoint.x() > bounds.x() + bounds.width() ){
|
---|
62 | _currentCenterPoint.setX(bounds.x() + bounds.width());
|
---|
63 |
|
---|
64 | }else if( centerPoint.x() < bounds.x() ){
|
---|
65 | _currentCenterPoint.setX(bounds.x());
|
---|
66 | }
|
---|
67 |
|
---|
68 | // opposite sign for latitude !
|
---|
69 | if( centerPoint.y() < - bounds.y() - bounds.height() ){
|
---|
70 | _currentCenterPoint.setY( - bounds.y() - bounds.height());
|
---|
71 |
|
---|
72 | }else if( centerPoint.y() > - bounds.y() ){
|
---|
73 | _currentCenterPoint.setY( - bounds.y());
|
---|
74 | }
|
---|
75 | }
|
---|
76 | }
|
---|
77 | // update the scrollbars
|
---|
78 | centerOn(_currentCenterPoint);
|
---|
79 | }
|
---|
80 |
|
---|
81 |
|
---|
82 | // -------------
|
---|
83 | void BncMapView::mousePressEvent(QMouseEvent* event)
|
---|
84 | {
|
---|
85 | // std::cout << " PRES " << event->pos().x() << " " << event->pos().y() << std::endl;
|
---|
86 | _lastPanPoint = event->pos();
|
---|
87 | setCursor(Qt::ClosedHandCursor);
|
---|
88 | }
|
---|
89 |
|
---|
90 |
|
---|
91 | // -------------
|
---|
92 | void BncMapView::mouseReleaseEvent(QMouseEvent* /* event */)
|
---|
93 | {
|
---|
94 | setCursor(Qt::OpenHandCursor);
|
---|
95 | _lastPanPoint = QPoint();
|
---|
96 | }
|
---|
97 |
|
---|
98 |
|
---|
99 | // -------------
|
---|
100 | void BncMapView::mouseMoveEvent(QMouseEvent* event)
|
---|
101 | {
|
---|
102 | if( !_lastPanPoint.isNull() ){
|
---|
103 |
|
---|
104 | // get how much we panned
|
---|
105 | QPointF delta = mapToScene(_lastPanPoint) - mapToScene(event->pos());
|
---|
106 | _lastPanPoint = event->pos();
|
---|
107 |
|
---|
108 | // update the center ie. do the pan
|
---|
109 | SetCenter(GetCenter() + delta);
|
---|
110 | }
|
---|
111 | }
|
---|
112 |
|
---|
113 |
|
---|
114 | // -------------
|
---|
115 | void BncMapView::wheelEvent(QWheelEvent* event)
|
---|
116 | {
|
---|
117 | // het the position of the mouse before scaling, in scene coords
|
---|
118 | QPointF pointBeforeScale(mapToScene(event->pos()));
|
---|
119 |
|
---|
120 | // get the original screen centerpoint
|
---|
121 | QPointF screenCenter = GetCenter();
|
---|
122 |
|
---|
123 | // scale the view ie. do the zoom
|
---|
124 | double scaleFactor = 1.10; // how fast we zoom
|
---|
125 | if( event->delta() > 0 ){
|
---|
126 |
|
---|
127 | // zooming in
|
---|
128 | scale( scaleFactor, scaleFactor );
|
---|
129 |
|
---|
130 | }else{
|
---|
131 |
|
---|
132 | // zooming out
|
---|
133 | scale( 1.0/scaleFactor, 1.0/scaleFactor );
|
---|
134 | }
|
---|
135 |
|
---|
136 | // get the position after scaling, in scene coords
|
---|
137 | QPointF pointAfterScale(mapToScene(event->pos()));
|
---|
138 |
|
---|
139 | // get the offset of how the screen moved
|
---|
140 | QPointF offset = pointBeforeScale - pointAfterScale;
|
---|
141 |
|
---|
142 | // adjust to the new center for correct zooming
|
---|
143 | QPointF newCenter = screenCenter + offset;
|
---|
144 | SetCenter(newCenter);
|
---|
145 | }
|
---|
146 |
|
---|
147 |
|
---|
148 | // -------------
|
---|
149 | void BncMapView::resizeEvent(QResizeEvent* event)
|
---|
150 | {
|
---|
151 | // get the rectangle of the visible area in scene coords
|
---|
152 | QRectF visibleArea = mapToScene(rect()).boundingRect();
|
---|
153 | SetCenter(visibleArea.center());
|
---|
154 |
|
---|
155 | // call the subclass resize so the scrollbars are updated correctly
|
---|
156 | QGraphicsView::resizeEvent(event);
|
---|
157 | }
|
---|