4423
+ − 1
#include <QDebug>
+ − 2
#include <QGraphicsSceneMouseEvent>
4426
+ − 3
#include <QGraphicsPathItem>
4427
+ − 4
#include <QtEndian>
4423
+ − 5
+ − 6
#include "drawmapscene.h"
+ − 7
4434
+ − 8
template <class T> T sqr(const T & x)
+ − 9
{
+ − 10
return x*x;
+ − 11
}
+ − 12
4423
+ − 13
DrawMapScene::DrawMapScene(QObject *parent) :
4424
+ − 14
QGraphicsScene(parent),
4426
+ − 15
m_pen(Qt::yellow),
+ − 16
m_brush(Qt::yellow)
4423
+ − 17
{
+ − 18
setSceneRect(0, 0, 4096, 2048);
4424
+ − 19
+ − 20
QLinearGradient gradient(0, 0, 0, 2048);
4426
+ − 21
gradient.setColorAt(0, QColor(60, 60, 155));
+ − 22
gradient.setColorAt(1, QColor(155, 155, 60));
4424
+ − 23
setBackgroundBrush(QBrush(gradient));
+ − 24
4426
+ − 25
m_pen.setWidth(67);
+ − 26
m_pen.setJoinStyle(Qt::RoundJoin);
+ − 27
m_pen.setCapStyle(Qt::RoundCap);
+ − 28
m_currPath = 0;
4423
+ − 29
}
+ − 30
+ − 31
void DrawMapScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent)
+ − 32
{
+ − 33
+ − 34
qDebug() << "move" << mouseEvent->scenePos();
4424
+ − 35
4426
+ − 36
if(m_currPath && (mouseEvent->buttons() & Qt::LeftButton))
+ − 37
{
+ − 38
QPainterPath path = m_currPath->path();
+ − 39
path.lineTo(mouseEvent->scenePos());
4439
+ − 40
paths.first().append(mouseEvent->scenePos().toPoint());
4426
+ − 41
m_currPath->setPath(path);
4427
+ − 42
+ − 43
emit pathChanged();
4426
+ − 44
}
4423
+ − 45
}
+ − 46
+ − 47
void DrawMapScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent)
+ − 48
{
+ − 49
qDebug() << "press" << mouseEvent->scenePos();
4424
+ − 50
4426
+ − 51
m_currPath = addPath(QPainterPath(), m_pen);
+ − 52
+ − 53
QPainterPath path = m_currPath->path();
+ − 54
QPointF p = mouseEvent->scenePos();
+ − 55
p += QPointF(0.01, 0.01);
+ − 56
path.moveTo(p);
+ − 57
path.lineTo(mouseEvent->scenePos());
4439
+ − 58
paths.prepend(QList<QPoint>() << mouseEvent->scenePos().toPoint());
4426
+ − 59
m_currPath->setPath(path);
+ − 60
4427
+ − 61
emit pathChanged();
4423
+ − 62
}
+ − 63
+ − 64
void DrawMapScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent)
+ − 65
{
+ − 66
qDebug() << "release" << mouseEvent->scenePos();
4426
+ − 67
4439
+ − 68
simplifyLast();
+ − 69
4426
+ − 70
m_currPath = 0;
4423
+ − 71
}
4424
+ − 72
4426
+ − 73
void DrawMapScene::undo()
4424
+ − 74
{
4426
+ − 75
if(items().size())
4427
+ − 76
{
4426
+ − 77
removeItem(items().first());
4439
+ − 78
paths.removeFirst();
4427
+ − 79
+ − 80
emit pathChanged();
+ − 81
}
4424
+ − 82
}
4427
+ − 83
+ − 84
QByteArray DrawMapScene::encode()
+ − 85
{
+ − 86
QByteArray b;
+ − 87
+ − 88
foreach(QList<QPoint> points, paths)
+ − 89
{
+ − 90
int cnt = 0;
+ − 91
foreach(QPoint point, points)
+ − 92
{
+ − 93
qint16 px = qToBigEndian((qint16)point.x());
+ − 94
qint16 py = qToBigEndian((qint16)point.y());
+ − 95
quint8 flags = 2;
4442
+ − 96
if(!cnt) flags |= 0x80;
4427
+ − 97
b.append((const char *)&px, 2);
+ − 98
b.append((const char *)&py, 2);
4457
+ − 99
b.append((const char *)&flags, 1);
4427
+ − 100
+ − 101
++cnt;
+ − 102
}
+ − 103
+ − 104
}
+ − 105
+ − 106
return b;
+ − 107
}
4434
+ − 108
4442
+ − 109
void DrawMapScene::decode(QByteArray data)
+ − 110
{
+ − 111
clear();
+ − 112
paths.clear();
+ − 113
+ − 114
QList<QPoint> points;
+ − 115
+ − 116
while(data.size() >= 5)
+ − 117
{
+ − 118
qint16 px = qFromBigEndian(*(qint16 *)data.data());
+ − 119
data.remove(0, 2);
+ − 120
qint16 py = qFromBigEndian(*(qint16 *)data.data());
+ − 121
data.remove(0, 2);
4457
+ − 122
quint8 flags = *(quint8 *)data.data();
+ − 123
data.remove(0, 1);
4442
+ − 124
+ − 125
//last chunk or first point
+ − 126
if((data.size() < 5) || (flags & 0x80))
+ − 127
{
+ − 128
if(points.size())
+ − 129
{
+ − 130
qDebug() << points;
+ − 131
addPath(pointsToPath(points), m_pen);
+ − 132
paths.prepend(points);
+ − 133
+ − 134
points.clear();
+ − 135
}
+ − 136
}
+ − 137
+ − 138
points.append(QPoint(px, py));
+ − 139
}
+ − 140
}
+ − 141
4439
+ − 142
void DrawMapScene::simplifyLast()
4434
+ − 143
{
4439
+ − 144
QList<QPoint> points = paths[0];
+ − 145
+ − 146
QPoint prevPoint = points.first();
+ − 147
int i = 1;
+ − 148
while(i < points.size())
4434
+ − 149
{
4471
+ − 150
if( (i != points.size() - 1)
+ − 151
&& (sqr(prevPoint.x() - points[i].x()) + sqr(prevPoint.y() - points[i].y()) < 1000)
+ − 152
)
4439
+ − 153
points.removeAt(i);
+ − 154
else
+ − 155
{
+ − 156
prevPoint = points[i];
+ − 157
++i;
+ − 158
}
+ − 159
}
4434
+ − 160
4439
+ − 161
paths[0] = points;
+ − 162
+ − 163
+ − 164
// redraw path
+ − 165
{
+ − 166
QGraphicsPathItem * pathItem = static_cast<QGraphicsPathItem *>(items()[0]);
4442
+ − 167
pathItem->setPath(pointsToPath(paths[0]));
4434
+ − 168
}
+ − 169
+ − 170
emit pathChanged();
+ − 171
}
4442
+ − 172
+ − 173
QPainterPath DrawMapScene::pointsToPath(const QList<QPoint> points)
+ − 174
{
+ − 175
QPainterPath path;
+ − 176
+ − 177
if(points.size())
+ − 178
{
+ − 179
QPointF p = points[0] + QPointF(0.01, 0.01);
+ − 180
path.moveTo(p);
+ − 181
+ − 182
foreach(QPoint p, points)
+ − 183
path.lineTo(p);
+ − 184
}
+ − 185
+ − 186
return path;
+ − 187
}