1 /**********************************************************************************************
2 Copyright (C) 2016 Oliver Eichler <oliver.eichler@gmx.de>
3 Copyright (C) 2018 Norbert Truchsess <norbert.truchsess@t-online.de>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 **********************************************************************************************/
19
20 #include "gis/CGisDraw.h"
21 #include "mouse/CMouseAdapter.h"
22 #include "mouse/IMouseSelect.h"
23 #include "mouse/IScrOpt.h"
24
25 #include <QPainterPath>
26 #include <QtWidgets>
27 #include <QPainterPath>
28
IMouseSelect(CGisDraw * gis,CCanvas * canvas,CMouseAdapter * mouse)29 IMouseSelect::IMouseSelect(CGisDraw* gis, CCanvas* canvas, CMouseAdapter* mouse)
30 : IMouse(gis, canvas, mouse)
31 {
32 }
33
~IMouseSelect()34 IMouseSelect::~IMouseSelect()
35 {
36 canvas->reportStatus("IMouseSelect", "");
37 delete scrOpt;
38 }
39
rectRad2Px(const QRectF & rectSrc,QRectF & rectTar) const40 void IMouseSelect::rectRad2Px(const QRectF& rectSrc, QRectF& rectTar) const
41 {
42 QPointF pt1 = rectSrc.topLeft();
43 QPointF pt2 = rectSrc.bottomRight();
44
45 gis->convertRad2Px(pt1);
46 gis->convertRad2Px(pt2);
47
48 rectTar = QRectF(pt1, pt2);
49 }
50
rectRad2Deg(const QRectF & rectSrc,QRectF & rectTar) const51 void IMouseSelect::rectRad2Deg(const QRectF& rectSrc, QRectF& rectTar) const
52 {
53 QPointF pt1 = rectSrc.topLeft();
54 QPointF pt2 = rectSrc.bottomRight();
55
56 pt1 *= RAD_TO_DEG;
57 pt2 *= RAD_TO_DEG;
58
59 rectTar = QRectF(pt1, pt2);
60 }
61
placeScrOpt()62 void IMouseSelect::placeScrOpt()
63 {
64 if(scrOpt.isNull())
65 {
66 return;
67 }
68
69 if((state == eStateMap) || (state == eStateMapMoving))
70 {
71 QRectF rectSel;
72 rectRad2Px(rectSelection, rectSel);
73 scrOpt->move(rectSel.topRight().toPoint());
74 scrOpt->show();
75 }
76 else
77 {
78 scrOpt->hide();
79 }
80 }
81
82
draw(QPainter & p,CCanvas::redraw_e needsRedraw,const QRect & rect)83 void IMouseSelect::draw(QPainter& p, CCanvas::redraw_e needsRedraw, const QRect& rect)
84 {
85 if(rectSelection.isNull())
86 {
87 return;
88 }
89
90 QRectF rectSel;
91 rectRad2Px(rectSelection, rectSel);
92
93 QRectF rectScr = canvas->rect();
94
95 rectTopLeft.moveTopLeft(rectSel.topLeft());
96 rectTopRight.moveTopRight(rectSel.topRight());
97 rectBottomLeft.moveBottomLeft(rectSel.bottomLeft());
98 rectBottomRight.moveBottomRight(rectSel.bottomRight());
99
100
101 QPainterPath path;
102 path.addRect(rectScr);
103 path.addRect(rectSel);
104
105 p.setPen(Qt::black);
106 p.setBrush(QColor(0, 0, 0, 128));
107 p.drawPath(path);
108
109 p.setBrush(Qt::lightGray);
110 p.drawRect(rectTopLeft);
111 p.drawRect(rectTopRight);
112 p.drawRect(rectBottomLeft);
113 p.drawRect(rectBottomRight);
114
115 p.setBrush(Qt::red);
116 switch(corner)
117 {
118 case eCornerTopLeft:
119 p.drawRect(rectTopLeft);
120 break;
121
122 case eCornerTopRight:
123 p.drawRect(rectTopRight);
124 break;
125
126 case eCornerBottomLeft:
127 p.drawRect(rectBottomLeft);
128 break;
129
130 case eCornerBottomRight:
131 p.drawRect(rectBottomRight);
132 break;
133 }
134
135 placeScrOpt();
136 }
137
leftButtonDown(const QPoint & point)138 void IMouseSelect::leftButtonDown(const QPoint& point)
139 {
140 canvas->reportStatus("IMouseSelect", "");
141 canvas->update();
142 }
143
mouseDragged(const QPoint & start,const QPoint & last,const QPoint & end)144 void IMouseSelect::mouseDragged(const QPoint& start, const QPoint& last, const QPoint& end)
145 {
146 switch(state)
147 {
148 case eStateIdle:
149 {
150 QPointF pos(start);
151 gis->convertPx2Rad(pos);
152 rectSelection.setTopLeft(pos);
153 rectSelection.setBottomRight(pos);
154 posInitial = pos;
155 state = eStateInitial;
156 break;
157 }
158
159 case eStateMap:
160 {
161 if(corner != eCornerNone)
162 {
163 state = eStateResize;
164 }
165 else
166 {
167 state = eStateMapMoving;
168 }
169 break;
170 }
171
172 case eStateInitial:
173 {
174 QPointF pos(end);
175 gis->convertPx2Rad(pos);
176
177 if(pos.x() < posInitial.x())
178 {
179 rectSelection.setLeft(pos.x());
180 }
181 else
182 {
183 rectSelection.setRight(pos.x());
184 }
185
186 if(pos.y() < posInitial.y())
187 {
188 rectSelection.setBottom(pos.y());
189 }
190 else
191 {
192 rectSelection.setTop(pos.y());
193 }
194
195 canvas->update();
196 break;
197 }
198
199 case eStateResize:
200 {
201 QPointF pos = end - offset;
202 gis->convertPx2Rad(pos);
203 switch(corner)
204 {
205 case eCornerTopLeft:
206 rectSelection.setTopLeft(pos);
207 break;
208
209 case eCornerTopRight:
210 rectSelection.setTopRight(pos);
211 break;
212
213 case eCornerBottomLeft:
214 rectSelection.setBottomLeft(pos);
215 break;
216
217 case eCornerBottomRight:
218 rectSelection.setBottomRight(pos);
219 break;
220 }
221
222 canvas->update();
223 break;
224 }
225
226 case eStateMapMoving:
227 {
228 IMouse::mouseDragged(start, last, end);
229 break;
230 }
231
232 default:
233 {
234 Q_ASSERT(false);
235 }
236 }
237 }
238
mouseMoved(const QPoint & pos)239 void IMouseSelect::mouseMoved(const QPoint& pos)
240 {
241 switch(state)
242 {
243 case eStateMap:
244 {
245 corner_e _corner = corner;
246 if(rectTopLeft.contains(pos))
247 {
248 offset = pos - rectTopLeft.topLeft();
249 corner = eCornerTopLeft;
250 }
251 else if(rectTopRight.contains(pos))
252 {
253 offset = pos - rectTopRight.topRight();
254 corner = eCornerTopRight;
255 }
256 else if(rectBottomLeft.contains(pos))
257 {
258 offset = pos - rectBottomLeft.bottomLeft();
259 corner = eCornerBottomLeft;
260 }
261 else if(rectBottomRight.contains(pos))
262 {
263 offset = pos - rectBottomRight.bottomRight();
264 corner = eCornerBottomRight;
265 }
266 else
267 {
268 corner = eCornerNone;
269 }
270
271 if(corner != _corner)
272 {
273 canvas->update();
274 }
275 break;
276 }
277 }
278 }
279
dragFinished(const QPoint & pos)280 void IMouseSelect::dragFinished(const QPoint& pos)
281 {
282 if(!rectSelection.isNull())
283 {
284 QPointF pt1 = rectSelection.topLeft();
285 QPointF pt2 = rectSelection.bottomRight();
286
287 gis->convertRad2Px(pt1);
288 gis->convertRad2Px(pt2);
289
290 QRectF rectSel(pt1, pt2);
291
292 if(rectSel.width() < 40 || rectSel.height() < 40)
293 {
294 rectSelection = QRectF();
295 }
296 }
297
298 state = rectSelection.isNull() ? eStateIdle : eStateMap;
299
300 canvas->update();
301 }
302