# HG changeset patch # User unc0rr # Date 1382095603 -14400 # Node ID 61f160dfd0f13d84f2e8b5d022a5f3eeeedc6783 # Parent ac5c1f691ce279e8bfbd6fa25084df8512937bbe Draw rectangles and ellipses! diff -r ac5c1f691ce2 -r 61f160dfd0f1 QTfrontend/drawmapscene.cpp --- a/QTfrontend/drawmapscene.cpp Tue Oct 15 23:07:22 2013 +0400 +++ b/QTfrontend/drawmapscene.cpp Fri Oct 18 15:26:43 2013 +0400 @@ -20,6 +20,7 @@ #include #include #include +#include #include "drawmapscene.h" @@ -44,6 +45,8 @@ setBackgroundBrush(m_eraser); m_isErasing = false; + m_pathType = Polyline; + m_pen.setWidth(76); m_pen.setJoinStyle(Qt::RoundJoin); m_pen.setCapStyle(Qt::RoundCap); @@ -61,18 +64,41 @@ { QPainterPath path = m_currPath->path(); - if(mouseEvent->modifiers() & Qt::ControlModifier) + switch (m_pathType) { - int c = path.elementCount(); - QPointF pos = mouseEvent->scenePos(); - path.setElementPositionAt(c - 1, pos.x(), pos.y()); + case Polyline: + if(mouseEvent->modifiers() & Qt::ControlModifier) + { + int c = path.elementCount(); + QPointF pos = mouseEvent->scenePos(); + path.setElementPositionAt(c - 1, pos.x(), pos.y()); + } + else + { + path.lineTo(mouseEvent->scenePos()); + paths.first().points.append(mouseEvent->scenePos().toPoint()); + } + break; + case Rectangle: { + path = QPainterPath(); + QPointF p1 = paths.first().initialPoint; + QPointF p2 = mouseEvent->scenePos(); + path.moveTo(p1); + path.lineTo(p1.x(), p2.y()); + path.lineTo(p2); + path.lineTo(p2.x(), p1.y()); + path.lineTo(p1); + break; + } + case Ellipse: { + path = QPainterPath(); + QList points = makeEllipse(paths.first().initialPoint, mouseEvent->scenePos()); + path.addPolygon(QPolygonF(QVector::fromList(points))); + break; } - else - { - path.lineTo(mouseEvent->scenePos()); - paths.first().points.append(mouseEvent->scenePos().toPoint()); } + m_currPath->setPath(path); emit pathChanged(); @@ -96,7 +122,8 @@ PathParams params; params.width = serializePenWidth(m_pen.width()); params.erasing = m_isErasing; - params.points = QList() << mouseEvent->scenePos().toPoint(); + params.initialPoint = mouseEvent->scenePos().toPoint(); + params.points = QList() << params.initialPoint; paths.prepend(params); m_currPath->setPath(path); @@ -107,10 +134,33 @@ { if (m_currPath) { - QPainterPath path = m_currPath->path(); - path.lineTo(mouseEvent->scenePos()); - paths.first().points.append(mouseEvent->scenePos().toPoint()); - m_currPath->setPath(path); + switch (m_pathType) + { + case Polyline: { + QPainterPath path = m_currPath->path(); + path.lineTo(mouseEvent->scenePos()); + paths.first().points.append(mouseEvent->scenePos().toPoint()); + m_currPath->setPath(path); + break; + } + case Rectangle: { + QPoint p1 = paths.first().initialPoint; + QPoint p2 = mouseEvent->scenePos().toPoint(); + QList rpoints; + rpoints << p1 << QPoint(p1.x(), p2.y()) << p2 << QPoint(p2.x(), p1.y()) << p1; + paths.first().points = rpoints; + break; + } + case Ellipse: + QPoint p1 = paths.first().initialPoint; + QPoint p2 = mouseEvent->scenePos().toPoint(); + QList points = makeEllipse(p1, p2); + QList epoints; + foreach(const QPointF & p, points) + epoints.append(p.toPoint()); + paths.first().points = epoints; + break; + } simplifyLast(); @@ -383,3 +433,29 @@ { return width * 10 + 6; } + +void DrawMapScene::setPathType(PathType pathType) +{ + m_pathType = pathType; +} + +QList DrawMapScene::makeEllipse(const QPointF ¢er, const QPointF &corner) +{ + QList l; + qreal r = (center - corner).manhattanLength(); + qreal rx = qAbs(center.x() - corner.x()); + qreal ry = qAbs(center.y() - corner.y()); + + if(r < 4) + { + l.append(center); + } else + { + qreal angleDelta = 12 / r; + for(qreal angle = 0.0; angle < 2*M_PI; angle += angleDelta) + l.append(center + QPointF(rx * cos(angle), ry * sin(angle))); + l.append(l.first()); + } + + return l; +} diff -r ac5c1f691ce2 -r 61f160dfd0f1 QTfrontend/drawmapscene.h --- a/QTfrontend/drawmapscene.h Tue Oct 15 23:07:22 2013 +0400 +++ b/QTfrontend/drawmapscene.h Fri Oct 18 15:26:43 2013 +0400 @@ -29,6 +29,7 @@ { quint8 width; bool erasing; + QPoint initialPoint; QList points; }; @@ -38,6 +39,12 @@ { Q_OBJECT public: + enum PathType { + Polyline = 0, + Rectangle = 1, + Ellipse = 2 + }; + explicit DrawMapScene(QObject *parent = 0); QByteArray encode(); @@ -54,6 +61,7 @@ void setErasing(bool erasing); void showCursor(); void hideCursor(); + void setPathType(PathType pathType); private: QPen m_pen; @@ -67,6 +75,7 @@ QGraphicsEllipseItem * m_cursor; bool m_isCursorShown; QByteArray m_specialPoints; + PathType m_pathType; virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent); virtual void mousePressEvent(QGraphicsSceneMouseEvent * mouseEvent); @@ -77,6 +86,7 @@ quint8 serializePenWidth(int width); int deserializePenWidth(quint8 width); + QList makeEllipse(const QPointF & center, const QPointF & corner); }; #endif // DRAWMAPSCENE_H diff -r ac5c1f691ce2 -r 61f160dfd0f1 QTfrontend/ui/page/pagedrawmap.cpp --- a/QTfrontend/ui/page/pagedrawmap.cpp Tue Oct 15 23:07:22 2013 +0400 +++ b/QTfrontend/ui/page/pagedrawmap.cpp Fri Oct 18 15:26:43 2013 +0400 @@ -20,6 +20,7 @@ #include #include #include +#include #include "pagedrawmap.h" #include "drawmapwidget.h" @@ -32,12 +33,22 @@ cbEraser = new QCheckBox(tr("Eraser"), this); pageLayout->addWidget(cbEraser, 0, 0); pbUndo = addButton(tr("Undo"), pageLayout, 1, 0); - pbClear = addButton(tr("Clear"), pageLayout, 2, 0); - pbLoad = addButton(tr("Load"), pageLayout, 3, 0); - pbSave = addButton(tr("Save"), pageLayout, 4, 0); + + rbPolyline = new QRadioButton(tr("Polyline"), this); + pageLayout->addWidget(rbPolyline, 2, 0); + rbRectangle = new QRadioButton(tr("Rectangle"), this); + pageLayout->addWidget(rbRectangle, 3, 0); + rbEllipse = new QRadioButton(tr("Ellipse"), this); + pageLayout->addWidget(rbEllipse, 4, 0); + + rbPolyline->setChecked(true); + + pbClear = addButton(tr("Clear"), pageLayout, 5, 0); + pbLoad = addButton(tr("Load"), pageLayout, 6, 0); + pbSave = addButton(tr("Save"), pageLayout, 7, 0); drawMapWidget = new DrawMapWidget(this); - pageLayout->addWidget(drawMapWidget, 0, 1, 6, 1); + pageLayout->addWidget(drawMapWidget, 0, 1, 9, 1); return pageLayout; } @@ -49,6 +60,10 @@ connect(pbClear, SIGNAL(clicked()), drawMapWidget, SLOT(clear())); connect(pbLoad, SIGNAL(clicked()), this, SLOT(load())); connect(pbSave, SIGNAL(clicked()), this, SLOT(save())); + + connect(rbPolyline, SIGNAL(toggled(bool)), this, SLOT(pathTypeSwitched(bool))); + connect(rbRectangle, SIGNAL(toggled(bool)), this, SLOT(pathTypeSwitched(bool))); + connect(rbEllipse, SIGNAL(toggled(bool)), this, SLOT(pathTypeSwitched(bool))); } PageDrawMap::PageDrawMap(QWidget* parent) : AbstractPage(parent) @@ -71,3 +86,13 @@ if(!fileName.isEmpty()) drawMapWidget->save(fileName); } + +void PageDrawMap::pathTypeSwitched(bool b) +{ + if(b) + { + if(rbPolyline->isChecked()) drawMapWidget->setPathType(DrawMapScene::Polyline); + else if(rbRectangle->isChecked()) drawMapWidget->setPathType(DrawMapScene::Rectangle); + else if(rbEllipse->isChecked()) drawMapWidget->setPathType(DrawMapScene::Ellipse); + } +} diff -r ac5c1f691ce2 -r 61f160dfd0f1 QTfrontend/ui/page/pagedrawmap.h --- a/QTfrontend/ui/page/pagedrawmap.h Tue Oct 15 23:07:22 2013 +0400 +++ b/QTfrontend/ui/page/pagedrawmap.h Fri Oct 18 15:26:43 2013 +0400 @@ -22,6 +22,7 @@ #include "AbstractPage.h" class DrawMapWidget; +class QRadioButton; class PageDrawMap : public AbstractPage { @@ -42,10 +43,14 @@ QPushButton * pbLoad; QPushButton * pbSave; QCheckBox * cbEraser; + QRadioButton * rbPolyline; + QRadioButton * rbRectangle; + QRadioButton * rbEllipse; private slots: void load(); void save(); + void pathTypeSwitched(bool b); }; #endif diff -r ac5c1f691ce2 -r 61f160dfd0f1 QTfrontend/ui/widget/drawmapwidget.cpp --- a/QTfrontend/ui/widget/drawmapwidget.cpp Tue Oct 15 23:07:22 2013 +0400 +++ b/QTfrontend/ui/widget/drawmapwidget.cpp Fri Oct 18 15:26:43 2013 +0400 @@ -123,6 +123,11 @@ if(m_scene) m_scene->setErasing(erasing); } +void DrawMapWidget::setPathType(DrawMapScene::PathType pathType) +{ + if(m_scene) m_scene->setPathType(pathType); +} + void DrawMapWidget::save(const QString & fileName) { if(m_scene) @@ -192,7 +197,7 @@ QGraphicsView::setScene(scene); } -// Why don't I ever recieve this event? +// Why don't I ever receive this event? void DrawMapView::enterEvent(QEvent *event) { if(m_scene) diff -r ac5c1f691ce2 -r 61f160dfd0f1 QTfrontend/ui/widget/drawmapwidget.h --- a/QTfrontend/ui/widget/drawmapwidget.h Tue Oct 15 23:07:22 2013 +0400 +++ b/QTfrontend/ui/widget/drawmapwidget.h Fri Oct 18 15:26:43 2013 +0400 @@ -100,6 +100,7 @@ void setErasing(bool erasing); void save(const QString & fileName); void load(const QString & fileName); + void setPathType(DrawMapScene::PathType pathType); protected: void changeEvent(QEvent *e);