1 /* |
1 /* |
2 * Hedgewars, a free turn based strategy game |
2 * Hedgewars, a free turn based strategy game |
3 * Copyright (c) 2012 Andrey Korotaev <unC0Rr@gmail.com> |
3 * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com> |
4 * |
4 * |
5 * This program is free software; you can redistribute it and/or modify |
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 |
6 * it under the terms of the GNU General Public License as published by |
7 * the Free Software Foundation; version 2 of the License |
7 * the Free Software Foundation; version 2 of the License |
8 * |
8 * |
29 } |
29 } |
30 |
30 |
31 DrawMapScene::DrawMapScene(QObject *parent) : |
31 DrawMapScene::DrawMapScene(QObject *parent) : |
32 QGraphicsScene(parent), |
32 QGraphicsScene(parent), |
33 m_pen(Qt::yellow), |
33 m_pen(Qt::yellow), |
34 m_brush(Qt::yellow) |
34 m_brush(Qt::yellow), |
|
35 m_cursor(new QGraphicsEllipseItem(-0.5, -0.5, 1, 1)) |
35 { |
36 { |
36 setSceneRect(0, 0, 4096, 2048); |
37 setSceneRect(0, 0, 4096, 2048); |
37 |
38 |
38 QLinearGradient gradient(0, 0, 0, 2048); |
39 QLinearGradient gradient(0, 0, 0, 2048); |
39 gradient.setColorAt(0, QColor(60, 60, 155)); |
40 gradient.setColorAt(0, QColor(60, 60, 155)); |
40 gradient.setColorAt(1, QColor(155, 155, 60)); |
41 gradient.setColorAt(1, QColor(155, 155, 60)); |
41 setBackgroundBrush(QBrush(gradient)); |
42 |
|
43 m_eraser = QBrush(gradient); |
|
44 setBackgroundBrush(m_eraser); |
|
45 m_isErasing = false; |
42 |
46 |
43 m_pen.setWidth(76); |
47 m_pen.setWidth(76); |
44 m_pen.setJoinStyle(Qt::RoundJoin); |
48 m_pen.setJoinStyle(Qt::RoundJoin); |
45 m_pen.setCapStyle(Qt::RoundCap); |
49 m_pen.setCapStyle(Qt::RoundCap); |
46 m_currPath = 0; |
50 m_currPath = 0; |
|
51 |
|
52 m_isCursorShown = false; |
|
53 m_cursor->setPen(QPen(Qt::green)); |
|
54 m_cursor->setZValue(1); |
|
55 m_cursor->setScale(m_pen.width()); |
47 } |
56 } |
48 |
57 |
49 void DrawMapScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) |
58 void DrawMapScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent) |
50 { |
59 { |
51 if(m_currPath && (mouseEvent->buttons() & Qt::LeftButton)) |
60 if(m_currPath && (mouseEvent->buttons() & Qt::LeftButton)) |
60 |
69 |
61 } |
70 } |
62 else |
71 else |
63 { |
72 { |
64 path.lineTo(mouseEvent->scenePos()); |
73 path.lineTo(mouseEvent->scenePos()); |
65 paths.first().second.append(mouseEvent->scenePos().toPoint()); |
74 paths.first().points.append(mouseEvent->scenePos().toPoint()); |
66 } |
75 } |
67 m_currPath->setPath(path); |
76 m_currPath->setPath(path); |
68 |
77 |
69 emit pathChanged(); |
78 emit pathChanged(); |
70 } |
79 } |
|
80 |
|
81 if(!m_isCursorShown) |
|
82 showCursor(); |
|
83 m_cursor->setPos(mouseEvent->scenePos()); |
71 } |
84 } |
72 |
85 |
73 void DrawMapScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent) |
86 void DrawMapScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent) |
74 { |
87 { |
75 m_currPath = addPath(QPainterPath(), m_pen); |
88 m_currPath = addPath(QPainterPath(), m_pen); |
77 QPainterPath path = m_currPath->path(); |
90 QPainterPath path = m_currPath->path(); |
78 QPointF p = mouseEvent->scenePos(); |
91 QPointF p = mouseEvent->scenePos(); |
79 p += QPointF(0.01, 0.01); |
92 p += QPointF(0.01, 0.01); |
80 path.moveTo(p); |
93 path.moveTo(p); |
81 path.lineTo(mouseEvent->scenePos()); |
94 path.lineTo(mouseEvent->scenePos()); |
82 paths.prepend(qMakePair(serializePenWidth(m_pen.width()), QList<QPoint>() << mouseEvent->scenePos().toPoint())); |
95 |
|
96 PathParams params; |
|
97 params.width = serializePenWidth(m_pen.width()); |
|
98 params.erasing = m_isErasing; |
|
99 params.points = QList<QPoint>() << mouseEvent->scenePos().toPoint(); |
|
100 paths.prepend(params); |
83 m_currPath->setPath(path); |
101 m_currPath->setPath(path); |
84 |
102 |
85 emit pathChanged(); |
103 emit pathChanged(); |
86 } |
104 } |
87 |
105 |
105 if(wheelEvent->delta() > 0 && m_pen.width() < 516) |
123 if(wheelEvent->delta() > 0 && m_pen.width() < 516) |
106 m_pen.setWidth(m_pen.width() + 10); |
124 m_pen.setWidth(m_pen.width() + 10); |
107 else if(wheelEvent->delta() < 0 && m_pen.width() >= 16) |
125 else if(wheelEvent->delta() < 0 && m_pen.width() >= 16) |
108 m_pen.setWidth(m_pen.width() - 10); |
126 m_pen.setWidth(m_pen.width() - 10); |
109 |
127 |
|
128 m_cursor->setScale(m_pen.width()); |
|
129 |
110 if(m_currPath) |
130 if(m_currPath) |
111 { |
131 { |
112 m_currPath->setPen(m_pen); |
132 m_currPath->setPen(m_pen); |
113 paths.first().first = serializePenWidth(m_pen.width()); |
133 paths.first().width = serializePenWidth(m_pen.width()); |
114 } |
134 } |
|
135 } |
|
136 |
|
137 void DrawMapScene::showCursor() |
|
138 { |
|
139 qDebug() << "show cursor"; |
|
140 if(!m_isCursorShown) |
|
141 addItem(m_cursor); |
|
142 |
|
143 m_isCursorShown = true; |
|
144 } |
|
145 |
|
146 void DrawMapScene::hideCursor() |
|
147 { |
|
148 qDebug() << "hide cursor"; |
|
149 if(m_isCursorShown) |
|
150 removeItem(m_cursor); |
|
151 |
|
152 m_isCursorShown = false; |
115 } |
153 } |
116 |
154 |
117 void DrawMapScene::undo() |
155 void DrawMapScene::undo() |
118 { |
156 { |
|
157 // cursor is a part of items() |
|
158 if(m_isCursorShown) |
|
159 return; |
|
160 |
119 if(items().size()) |
161 if(items().size()) |
120 { |
162 { |
121 removeItem(items().first()); |
163 removeItem(items().first()); |
122 paths.removeFirst(); |
164 paths.removeFirst(); |
123 |
165 |
153 paths.clear(); |
199 paths.clear(); |
154 |
200 |
155 emit pathChanged(); |
201 emit pathChanged(); |
156 } |
202 } |
157 |
203 |
|
204 |
|
205 void DrawMapScene::setErasing(bool erasing) |
|
206 { |
|
207 m_isErasing = erasing; |
|
208 if(erasing) |
|
209 m_pen.setBrush(m_eraser); |
|
210 else |
|
211 m_pen.setBrush(m_brush); |
|
212 } |
|
213 |
158 QByteArray DrawMapScene::encode() |
214 QByteArray DrawMapScene::encode() |
159 { |
215 { |
160 QByteArray b; |
216 QByteArray b; |
161 |
217 |
162 for(int i = paths.size() - 1; i >= 0; --i) |
218 for(int i = paths.size() - 1; i >= 0; --i) |
163 { |
219 { |
164 int cnt = 0; |
220 int cnt = 0; |
165 QPair<quint8, QList<QPoint> > points = paths.at(i); |
221 PathParams params = paths.at(i); |
166 foreach(QPoint point, points.second) |
222 foreach(QPoint point, params.points) |
167 { |
223 { |
168 qint16 px = qToBigEndian((qint16)point.x()); |
224 qint16 px = qToBigEndian((qint16)point.x()); |
169 qint16 py = qToBigEndian((qint16)point.y()); |
225 qint16 py = qToBigEndian((qint16)point.y()); |
170 quint8 flags = 0; |
226 quint8 flags = 0; |
171 if(!cnt) flags = 0x80 + points.first; |
227 if(!cnt) flags = 0x80 + params.width; |
|
228 if(params.erasing) flags |= 0x40; |
172 b.append((const char *)&px, 2); |
229 b.append((const char *)&px, 2); |
173 b.append((const char *)&py, 2); |
230 b.append((const char *)&py, 2); |
174 b.append((const char *)&flags, 1); |
231 b.append((const char *)&flags, 1); |
175 |
232 |
176 ++cnt; |
233 ++cnt; |
199 quint8 flags = *(quint8 *)data.data(); |
258 quint8 flags = *(quint8 *)data.data(); |
200 data.remove(0, 1); |
259 data.remove(0, 1); |
201 |
260 |
202 if(flags & 0x80) |
261 if(flags & 0x80) |
203 { |
262 { |
204 if(points.second.size()) |
263 if(params.points.size()) |
205 { |
264 { |
206 addPath(pointsToPath(points.second), m_pen); |
265 addPath(pointsToPath(params.points), m_pen); |
207 |
266 |
208 paths.prepend(points); |
267 paths.prepend(params); |
209 |
268 |
210 points.second.clear(); |
269 params.points.clear(); |
211 } |
270 } |
212 |
271 |
213 quint8 penWidth = flags & 0x7f; |
272 quint8 penWidth = flags & 0x3f; |
214 m_pen.setWidth(deserializePenWidth(penWidth)); |
273 m_pen.setWidth(deserializePenWidth(penWidth)); |
215 points.first = penWidth; |
274 if(flags & 0x40) |
216 } |
275 m_pen.setBrush(m_eraser); |
217 |
276 else |
218 points.second.append(QPoint(px, py)); |
277 m_pen.setBrush(m_brush); |
219 } |
278 params.width = penWidth; |
220 |
279 } |
221 if(points.second.size()) |
280 |
222 { |
281 params.points.append(QPoint(px, py)); |
223 addPath(pointsToPath(points.second), m_pen); |
282 } |
224 paths.prepend(points); |
283 |
|
284 if(params.points.size()) |
|
285 { |
|
286 addPath(pointsToPath(params.points), m_pen); |
|
287 paths.prepend(params); |
225 } |
288 } |
226 |
289 |
227 emit pathChanged(); |
290 emit pathChanged(); |
|
291 |
|
292 setErasing(erasing); |
228 } |
293 } |
229 |
294 |
230 void DrawMapScene::simplifyLast() |
295 void DrawMapScene::simplifyLast() |
231 { |
296 { |
232 if(!paths.size()) return; |
297 if(!paths.size()) return; |
233 |
298 |
234 QList<QPoint> points = paths.at(0).second; |
299 QList<QPoint> points = paths.at(0).points; |
235 |
300 |
236 QPoint prevPoint = points.first(); |
301 QPoint prevPoint = points.first(); |
237 int i = 1; |
302 int i = 1; |
238 while(i < points.size()) |
303 while(i < points.size()) |
239 { |
304 { |
246 prevPoint = points[i]; |
311 prevPoint = points[i]; |
247 ++i; |
312 ++i; |
248 } |
313 } |
249 } |
314 } |
250 |
315 |
251 paths[0].second = points; |
316 paths[0].points = points; |
252 |
317 |
253 |
318 |
254 // redraw path |
319 // redraw path |
255 { |
320 { |
256 QGraphicsPathItem * pathItem = static_cast<QGraphicsPathItem *>(items()[0]); |
321 QGraphicsPathItem * pathItem = static_cast<QGraphicsPathItem *>(items()[m_isCursorShown ? 1 : 0]); |
257 pathItem->setPath(pointsToPath(paths[0].second)); |
322 pathItem->setPath(pointsToPath(paths[0].points)); |
258 } |
323 } |
259 |
324 |
260 emit pathChanged(); |
325 emit pathChanged(); |
|
326 } |
|
327 |
|
328 int DrawMapScene::pointsCount() |
|
329 { |
|
330 int cnt = 0; |
|
331 foreach(PathParams p, paths) |
|
332 cnt += p.points.size(); |
|
333 |
|
334 return cnt; |
261 } |
335 } |
262 |
336 |
263 QPainterPath DrawMapScene::pointsToPath(const QList<QPoint> points) |
337 QPainterPath DrawMapScene::pointsToPath(const QList<QPoint> points) |
264 { |
338 { |
265 QPainterPath path; |
339 QPainterPath path; |