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 { |
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 ¢er, 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 } |