--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/QTfrontend/drawmapscene.cpp Mon Dec 13 22:12:30 2010 +0300
@@ -0,0 +1,178 @@
+#include <QGraphicsSceneMouseEvent>
+#include <QGraphicsPathItem>
+#include <QtEndian>
+
+#include "drawmapscene.h"
+
+template <class T> T sqr(const T & x)
+{
+ return x*x;
+}
+
+DrawMapScene::DrawMapScene(QObject *parent) :
+ QGraphicsScene(parent),
+ m_pen(Qt::yellow),
+ m_brush(Qt::yellow)
+{
+ setSceneRect(0, 0, 4096, 2048);
+
+ QLinearGradient gradient(0, 0, 0, 2048);
+ gradient.setColorAt(0, QColor(60, 60, 155));
+ gradient.setColorAt(1, QColor(155, 155, 60));
+ setBackgroundBrush(QBrush(gradient));
+
+ m_pen.setWidth(67);
+ m_pen.setJoinStyle(Qt::RoundJoin);
+ m_pen.setCapStyle(Qt::RoundCap);
+ m_currPath = 0;
+}
+
+void DrawMapScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent)
+{
+ if(m_currPath && (mouseEvent->buttons() & Qt::LeftButton))
+ {
+ QPainterPath path = m_currPath->path();
+ path.lineTo(mouseEvent->scenePos());
+ paths.first().append(mouseEvent->scenePos().toPoint());
+ m_currPath->setPath(path);
+
+ emit pathChanged();
+ }
+}
+
+void DrawMapScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent)
+{
+ m_currPath = addPath(QPainterPath(), m_pen);
+
+ QPainterPath path = m_currPath->path();
+ QPointF p = mouseEvent->scenePos();
+ p += QPointF(0.01, 0.01);
+ path.moveTo(p);
+ path.lineTo(mouseEvent->scenePos());
+ paths.prepend(QList<QPoint>() << mouseEvent->scenePos().toPoint());
+ m_currPath->setPath(path);
+
+ emit pathChanged();
+}
+
+void DrawMapScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent)
+{
+ simplifyLast();
+
+ m_currPath = 0;
+}
+
+void DrawMapScene::undo()
+{
+ if(items().size())
+ {
+ removeItem(items().first());
+ paths.removeFirst();
+
+ emit pathChanged();
+ }
+}
+
+QByteArray DrawMapScene::encode()
+{
+ QByteArray b;
+
+ foreach(QList<QPoint> points, paths)
+ {
+ int cnt = 0;
+ foreach(QPoint point, points)
+ {
+ qint16 px = qToBigEndian((qint16)point.x());
+ qint16 py = qToBigEndian((qint16)point.y());
+ quint8 flags = 2;
+ if(!cnt) flags |= 0x80;
+ b.append((const char *)&px, 2);
+ b.append((const char *)&py, 2);
+ b.append((const char *)&flags, 1);
+
+ ++cnt;
+ }
+
+ }
+
+ return b;
+}
+
+void DrawMapScene::decode(QByteArray data)
+{
+ clear();
+ paths.clear();
+
+ QList<QPoint> points;
+
+ while(data.size() >= 5)
+ {
+ qint16 px = qFromBigEndian(*(qint16 *)data.data());
+ data.remove(0, 2);
+ qint16 py = qFromBigEndian(*(qint16 *)data.data());
+ data.remove(0, 2);
+ quint8 flags = *(quint8 *)data.data();
+ data.remove(0, 1);
+
+ //last chunk or first point
+ if((data.size() < 5) || (flags & 0x80))
+ {
+ if(points.size())
+ {
+ addPath(pointsToPath(points), m_pen);
+ paths.prepend(points);
+
+ points.clear();
+ }
+ }
+
+ points.append(QPoint(px, py));
+ }
+}
+
+void DrawMapScene::simplifyLast()
+{
+ QList<QPoint> points = paths[0];
+
+ QPoint prevPoint = points.first();
+ int i = 1;
+ while(i < points.size())
+ {
+ if( (i != points.size() - 1)
+ && (sqr(prevPoint.x() - points[i].x()) + sqr(prevPoint.y() - points[i].y()) < 1000)
+ )
+ points.removeAt(i);
+ else
+ {
+ prevPoint = points[i];
+ ++i;
+ }
+ }
+
+ paths[0] = points;
+
+
+ // redraw path
+ {
+ QGraphicsPathItem * pathItem = static_cast<QGraphicsPathItem *>(items()[0]);
+ pathItem->setPath(pointsToPath(paths[0]));
+ }
+
+ emit pathChanged();
+}
+
+QPainterPath DrawMapScene::pointsToPath(const QList<QPoint> points)
+{
+ QPainterPath path;
+
+ if(points.size())
+ {
+ QPointF p = points[0] + QPointF(0.01, 0.01);
+ path.moveTo(p);
+
+ foreach(QPoint p, points)
+ path.lineTo(p);
+ }
+
+ return path;
+}