QTfrontend/drawmapscene.cpp
branchwebgl
changeset 9950 2759212a27de
parent 9555 485b424be769
child 9928 fe4b1ce9b6f8
child 9998 736015b847e3
equal deleted inserted replaced
9521:8054d9d775fd 9950:2759212a27de
    18 
    18 
    19 #include <QGraphicsSceneMouseEvent>
    19 #include <QGraphicsSceneMouseEvent>
    20 #include <QGraphicsPathItem>
    20 #include <QGraphicsPathItem>
    21 #include <QtEndian>
    21 #include <QtEndian>
    22 #include <QDebug>
    22 #include <QDebug>
       
    23 #include <QTransform>
       
    24 #include <math.h>
    23 
    25 
    24 #include "drawmapscene.h"
    26 #include "drawmapscene.h"
    25 
    27 
    26 template <class T> T sqr(const T & x)
    28 template <class T> T sqr(const T & x)
    27 {
    29 {
    42 
    44 
    43     m_eraser = QBrush(gradient);
    45     m_eraser = QBrush(gradient);
    44     setBackgroundBrush(m_eraser);
    46     setBackgroundBrush(m_eraser);
    45     m_isErasing = false;
    47     m_isErasing = false;
    46 
    48 
       
    49     m_pathType = Polyline;
       
    50 
    47     m_pen.setWidth(76);
    51     m_pen.setWidth(76);
    48     m_pen.setJoinStyle(Qt::RoundJoin);
    52     m_pen.setJoinStyle(Qt::RoundJoin);
    49     m_pen.setCapStyle(Qt::RoundCap);
    53     m_pen.setCapStyle(Qt::RoundCap);
    50     m_currPath = 0;
    54     m_currPath = 0;
    51 
    55 
    58 void DrawMapScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent)
    62 void DrawMapScene::mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent)
    59 {
    63 {
    60     if(m_currPath && (mouseEvent->buttons() & Qt::LeftButton))
    64     if(m_currPath && (mouseEvent->buttons() & Qt::LeftButton))
    61     {
    65     {
    62         QPainterPath path = m_currPath->path();
    66         QPainterPath path = m_currPath->path();
       
    67         QPointF currentPos = mouseEvent->scenePos();
    63 
    68 
    64         if(mouseEvent->modifiers() & Qt::ControlModifier)
    69         if(mouseEvent->modifiers() & Qt::ControlModifier)
       
    70             currentPos = putSomeConstraints(paths.first().initialPoint, currentPos);
       
    71 
       
    72         switch (m_pathType)
    65         {
    73         {
    66             int c = path.elementCount();
    74         case Polyline:
    67             QPointF pos = mouseEvent->scenePos();
    75             if(mouseEvent->modifiers() & Qt::ControlModifier)
    68             path.setElementPositionAt(c - 1, pos.x(), pos.y());
    76             {
    69 
    77                 int c = path.elementCount();
    70         }
    78                 path.setElementPositionAt(c - 1, currentPos.x(), currentPos.y());
    71         else
    79 
    72         {
    80             }
    73             path.lineTo(mouseEvent->scenePos());
    81             else
    74             paths.first().points.append(mouseEvent->scenePos().toPoint());
    82             {
    75         }
    83                 path.lineTo(currentPos);
       
    84                 paths.first().points.append(mouseEvent->scenePos().toPoint());
       
    85             }
       
    86             break;
       
    87         case Rectangle: {
       
    88             path = QPainterPath();
       
    89             QPointF p1 = paths.first().initialPoint;
       
    90             QPointF p2 = currentPos;
       
    91             path.moveTo(p1);
       
    92             path.lineTo(p1.x(), p2.y());
       
    93             path.lineTo(p2);
       
    94             path.lineTo(p2.x(), p1.y());
       
    95             path.lineTo(p1);
       
    96             break;
       
    97             }
       
    98         case Ellipse: {
       
    99             path = QPainterPath();
       
   100             QList<QPointF> points = makeEllipse(paths.first().initialPoint, currentPos);
       
   101             path.addPolygon(QPolygonF(QVector<QPointF>::fromList(points)));
       
   102             break;
       
   103         }
       
   104         }
       
   105 
    76         m_currPath->setPath(path);
   106         m_currPath->setPath(path);
    77 
   107 
    78         emit pathChanged();
   108         emit pathChanged();
    79     }
   109     }
    80 
   110 
    94     path.lineTo(mouseEvent->scenePos());
   124     path.lineTo(mouseEvent->scenePos());
    95 
   125 
    96     PathParams params;
   126     PathParams params;
    97     params.width = serializePenWidth(m_pen.width());
   127     params.width = serializePenWidth(m_pen.width());
    98     params.erasing = m_isErasing;
   128     params.erasing = m_isErasing;
    99     params.points = QList<QPoint>() << mouseEvent->scenePos().toPoint();
   129     params.initialPoint = mouseEvent->scenePos().toPoint();
       
   130     params.points = QList<QPoint>() << params.initialPoint;
   100     paths.prepend(params);
   131     paths.prepend(params);
   101     m_currPath->setPath(path);
   132     m_currPath->setPath(path);
   102 
   133 
   103     emit pathChanged();
   134     emit pathChanged();
   104 }
   135 }
   105 
   136 
   106 void DrawMapScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent)
   137 void DrawMapScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * mouseEvent)
   107 {
   138 {
   108     if (m_currPath)
   139     if (m_currPath)
   109     {
   140     {
   110         QPainterPath path = m_currPath->path();
   141         QPointF currentPos = mouseEvent->scenePos();
   111         path.lineTo(mouseEvent->scenePos());
   142 
   112         paths.first().points.append(mouseEvent->scenePos().toPoint());
   143         if(mouseEvent->modifiers() & Qt::ControlModifier)
   113         m_currPath->setPath(path);
   144             currentPos = putSomeConstraints(paths.first().initialPoint, currentPos);
   114 
   145 
   115         simplifyLast();
   146         switch (m_pathType)
       
   147         {
       
   148         case Polyline: {
       
   149             QPainterPath path = m_currPath->path();
       
   150             path.lineTo(mouseEvent->scenePos());
       
   151             paths.first().points.append(currentPos.toPoint());
       
   152             m_currPath->setPath(path);
       
   153             simplifyLast();
       
   154             break;
       
   155         }
       
   156         case Rectangle: {
       
   157             QPoint p1 = paths.first().initialPoint;
       
   158             QPoint p2 = currentPos.toPoint();
       
   159             QList<QPoint> rpoints;
       
   160             rpoints << p1 << QPoint(p1.x(), p2.y()) << p2 << QPoint(p2.x(), p1.y()) << p1;
       
   161             paths.first().points = rpoints;
       
   162             break;
       
   163         }
       
   164         case Ellipse:
       
   165             QPoint p1 = paths.first().initialPoint;
       
   166             QPoint p2 = currentPos.toPoint();
       
   167             QList<QPointF> points = makeEllipse(p1, p2);
       
   168             QList<QPoint> epoints;
       
   169             foreach(const QPointF & p, points)
       
   170                 epoints.append(p.toPoint());
       
   171             paths.first().points = epoints;
       
   172             break;
       
   173         }
   116 
   174 
   117         m_currPath = 0;
   175         m_currPath = 0;
       
   176 
       
   177         emit pathChanged();
   118     }
   178     }
   119 }
   179 }
   120 
   180 
   121 void DrawMapScene::wheelEvent(QGraphicsSceneWheelEvent * wheelEvent)
   181 void DrawMapScene::wheelEvent(QGraphicsSceneWheelEvent * wheelEvent)
   122 {
   182 {
   343     // redraw path
   403     // redraw path
   344     {
   404     {
   345         QGraphicsPathItem * pathItem = static_cast<QGraphicsPathItem *>(items()[m_isCursorShown ? 1 : 0]);
   405         QGraphicsPathItem * pathItem = static_cast<QGraphicsPathItem *>(items()[m_isCursorShown ? 1 : 0]);
   346         pathItem->setPath(pointsToPath(paths[0].points));
   406         pathItem->setPath(pointsToPath(paths[0].points));
   347     }
   407     }
   348 
       
   349     emit pathChanged();
       
   350 }
   408 }
   351 
   409 
   352 int DrawMapScene::pointsCount()
   410 int DrawMapScene::pointsCount()
   353 {
   411 {
   354     int cnt = 0;
   412     int cnt = 0;
   381 
   439 
   382 int DrawMapScene::deserializePenWidth(quint8 width)
   440 int DrawMapScene::deserializePenWidth(quint8 width)
   383 {
   441 {
   384     return width * 10 + 6;
   442     return width * 10 + 6;
   385 }
   443 }
       
   444 
       
   445 void DrawMapScene::setPathType(PathType pathType)
       
   446 {
       
   447     m_pathType = pathType;
       
   448 }
       
   449 
       
   450 QList<QPointF> DrawMapScene::makeEllipse(const QPointF &center, const QPointF &corner)
       
   451 {
       
   452     QList<QPointF> l;
       
   453     qreal rx = qAbs(center.x() - corner.x());
       
   454     qreal ry = qAbs(center.y() - corner.y());
       
   455     qreal r = qMax(rx, ry);
       
   456 
       
   457     if(r < 4)
       
   458     {
       
   459         l.append(center);
       
   460     } else
       
   461     {
       
   462         qreal angleDelta = qMax(0.1, qMin(0.7, 120 / r));
       
   463         for(qreal angle = 0.0; angle < 2*M_PI; angle += angleDelta)
       
   464             l.append(center + QPointF(rx * cos(angle), ry * sin(angle)));
       
   465         l.append(l.first());
       
   466     }
       
   467 
       
   468     return l;
       
   469 }
       
   470 
       
   471 QPointF DrawMapScene::putSomeConstraints(const QPointF &initialPoint, const QPointF &point)
       
   472 {
       
   473     QPointF vector = point - initialPoint;
       
   474 
       
   475     for(int angle = 0; angle < 180; angle += 15)
       
   476     {
       
   477         QTransform transform;
       
   478         transform.rotate(angle);
       
   479 
       
   480         QPointF rotated = transform.map(vector);
       
   481 
       
   482         if(rotated.x() == 0) return point;
       
   483         if(qAbs(rotated.y() / rotated.x()) < 0.05) return initialPoint + transform.inverted().map(QPointF(rotated.x(), 0));
       
   484     }
       
   485 
       
   486     return point;
       
   487 }