tools/drawMapTest/drawmapscene.cpp
changeset 14354 20178fa3a74a
parent 14353 5cc671f988e7
child 14355 bc29fc6df7a2
equal deleted inserted replaced
14353:5cc671f988e7 14354:20178fa3a74a
     1 #include <QDebug>
       
     2 #include <QGraphicsSceneMouseEvent>
       
     3 #include <QGraphicsPathItem>
       
     4 #include <QtEndian>
       
     5 
       
     6 #include "drawmapscene.h"
       
     7 
       
     8 template <class T> T sqr(const T & x)
       
     9 {
       
    10     return x*x;
       
    11 }
       
    12 
       
    13 DrawMapScene::DrawMapScene(QObject *parent) :
       
    14     QGraphicsScene(parent),
       
    15     m_pen(Qt::yellow),
       
    16     m_brush(Qt::yellow)
       
    17 {
       
    18     setSceneRect(0, 0, 4096, 2048);
       
    19 
       
    20     QLinearGradient gradient(0, 0, 0, 2048);
       
    21     gradient.setColorAt(0, QColor(60, 60, 155));
       
    22     gradient.setColorAt(1, QColor(155, 155, 60));
       
    23     setBackgroundBrush(QBrush(gradient));
       
    24 
       
    25     m_pen.setWidth(67);
       
    26     m_pen.setJoinStyle(Qt::RoundJoin);
       
    27     m_pen.setCapStyle(Qt::RoundCap);
       
    28     m_currPath = 0;
       
    29 }
       
    30 
       
    31 void DrawMapScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent)
       
    32 {
       
    33 
       
    34     qDebug() << "move" << mouseEvent->scenePos();
       
    35 
       
    36     if(m_currPath && (mouseEvent->buttons() & Qt::LeftButton))
       
    37     {
       
    38         QPainterPath path = m_currPath->path();
       
    39         path.lineTo(mouseEvent->scenePos());
       
    40         paths.first().append(mouseEvent->scenePos().toPoint());
       
    41         m_currPath->setPath(path);
       
    42 
       
    43         emit pathChanged();
       
    44     }
       
    45 }
       
    46 
       
    47 void DrawMapScene::mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent)
       
    48 {
       
    49     qDebug() << "press" << mouseEvent->scenePos();
       
    50 
       
    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());
       
    58     paths.prepend(QList<QPoint>() << mouseEvent->scenePos().toPoint());
       
    59     m_currPath->setPath(path);
       
    60 
       
    61     emit pathChanged();
       
    62 }
       
    63 
       
    64 void DrawMapScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent)
       
    65 {
       
    66     qDebug() << "release" << mouseEvent->scenePos();
       
    67 
       
    68     simplifyLast();
       
    69 
       
    70     m_currPath = 0;
       
    71 }
       
    72 
       
    73 void DrawMapScene::undo()
       
    74 {
       
    75     if(items().size())
       
    76     {
       
    77         removeItem(items().first());
       
    78         paths.removeFirst();
       
    79 
       
    80         emit pathChanged();
       
    81     }
       
    82 }
       
    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;
       
    96             if(!cnt) flags |= 0x80;
       
    97             b.append((const char *)&px, 2);
       
    98             b.append((const char *)&py, 2);
       
    99             b.append((const char *)&flags, 1);
       
   100 
       
   101             ++cnt;
       
   102         }
       
   103 
       
   104     }
       
   105 
       
   106     return b;
       
   107 }
       
   108 
       
   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);
       
   122         quint8 flags = *(quint8 *)data.data();
       
   123         data.remove(0, 1);
       
   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 
       
   142 void DrawMapScene::simplifyLast()
       
   143 {
       
   144     QList<QPoint> points = paths[0];
       
   145 
       
   146     QPoint prevPoint = points.first();
       
   147     int i = 1;
       
   148     while(i < points.size())
       
   149     {
       
   150         if( (i != points.size() - 1)
       
   151             && (sqr(prevPoint.x() - points[i].x()) + sqr(prevPoint.y() - points[i].y()) < 1000)
       
   152           )
       
   153             points.removeAt(i);
       
   154         else
       
   155         {
       
   156             prevPoint = points[i];
       
   157             ++i;
       
   158         }
       
   159     }
       
   160 
       
   161     paths[0] = points;
       
   162 
       
   163 
       
   164     // redraw path
       
   165     {
       
   166         QGraphicsPathItem * pathItem = static_cast<QGraphicsPathItem *>(items()[0]);
       
   167         pathItem->setPath(pointsToPath(paths[0]));
       
   168     }
       
   169 
       
   170     emit pathChanged();
       
   171 }
       
   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 }