Eraser tool
authorunc0rr
Mon, 09 Apr 2012 22:01:36 +0400
changeset 6873 30840365af0a
parent 6872 0f6eef4a07c8
child 6874 b9e2e509a42d
Eraser tool
QTfrontend/drawmapscene.cpp
QTfrontend/drawmapscene.h
QTfrontend/ui/page/pagedrawmap.cpp
QTfrontend/ui/page/pagedrawmap.h
QTfrontend/ui/widget/drawmapwidget.cpp
QTfrontend/ui/widget/drawmapwidget.h
hedgewars/pas2cSystem.pas
hedgewars/uLandPainted.pas
--- a/QTfrontend/drawmapscene.cpp	Mon Apr 09 22:01:13 2012 +0400
+++ b/QTfrontend/drawmapscene.cpp	Mon Apr 09 22:01:36 2012 +0400
@@ -38,7 +38,10 @@
     QLinearGradient gradient(0, 0, 0, 2048);
     gradient.setColorAt(0, QColor(60, 60, 155));
     gradient.setColorAt(1, QColor(155, 155, 60));
-    setBackgroundBrush(QBrush(gradient));
+
+    m_eraser = QBrush(gradient);
+    setBackgroundBrush(m_eraser);
+    m_isErasing = false;
 
     m_pen.setWidth(76);
     m_pen.setJoinStyle(Qt::RoundJoin);
@@ -62,7 +65,7 @@
         else
         {
             path.lineTo(mouseEvent->scenePos());
-            paths.first().second.append(mouseEvent->scenePos().toPoint());
+            paths.first().points.append(mouseEvent->scenePos().toPoint());
         }
         m_currPath->setPath(path);
 
@@ -79,7 +82,12 @@
     p += QPointF(0.01, 0.01);
     path.moveTo(p);
     path.lineTo(mouseEvent->scenePos());
-    paths.prepend(qMakePair(serializePenWidth(m_pen.width()), QList<QPoint>() << mouseEvent->scenePos().toPoint()));
+
+    PathParams params;
+    params.width = serializePenWidth(m_pen.width());
+    params.erasing = m_isErasing;
+    params.points = QList<QPoint>() << mouseEvent->scenePos().toPoint();
+    paths.prepend(params);
     m_currPath->setPath(path);
 
     emit pathChanged();
@@ -91,7 +99,7 @@
     {
         QPainterPath path = m_currPath->path();
         path.lineTo(mouseEvent->scenePos());
-        paths.first().second.append(mouseEvent->scenePos().toPoint());
+        paths.first().points.append(mouseEvent->scenePos().toPoint());
         m_currPath->setPath(path);
 
         simplifyLast();
@@ -110,7 +118,7 @@
     if(m_currPath)
     {
         m_currPath->setPen(m_pen);
-        paths.first().first = serializePenWidth(m_pen.width());
+        paths.first().width = serializePenWidth(m_pen.width());
     }
 }
 
@@ -155,6 +163,16 @@
     emit pathChanged();
 }
 
+
+void DrawMapScene::setErasing(bool erasing)
+{
+    m_isErasing = erasing;
+    if(erasing)
+        m_pen.setBrush(m_eraser);
+    else
+        m_pen.setBrush(m_brush);
+}
+
 QByteArray DrawMapScene::encode()
 {
     QByteArray b;
@@ -162,13 +180,14 @@
     for(int i = paths.size() - 1; i >= 0; --i)
     {
         int cnt = 0;
-        QPair<quint8, QList<QPoint> > points = paths.at(i);
-        foreach(QPoint point, points.second)
+        PathParams params = paths.at(i);
+        foreach(QPoint point, params.points)
         {
             qint16 px = qToBigEndian((qint16)point.x());
             qint16 py = qToBigEndian((qint16)point.y());
             quint8 flags = 0;
-            if(!cnt) flags = 0x80 + points.first;
+            if(!cnt) flags = 0x80 + params.width;
+            if(params.erasing) flags |= 0x40;
             b.append((const char *)&px, 2);
             b.append((const char *)&py, 2);
             b.append((const char *)&flags, 1);
@@ -183,12 +202,14 @@
 
 void DrawMapScene::decode(QByteArray data)
 {
+    bool erasing = m_isErasing;
+
     oldItems.clear();
     oldPaths.clear();
     clear();
     paths.clear();
 
-    QPair<quint8, QList<QPoint> > points;
+    PathParams params;
 
     while(data.size() >= 5)
     {
@@ -201,37 +222,43 @@
 
         if(flags & 0x80)
         {
-            if(points.second.size())
+            if(params.points.size())
             {
-                addPath(pointsToPath(points.second), m_pen);
+                addPath(pointsToPath(params.points), m_pen);
 
-                paths.prepend(points);
+                paths.prepend(params);
 
-                points.second.clear();
+                params.points.clear();
             }
 
-            quint8 penWidth = flags & 0x7f;
+            quint8 penWidth = flags & 0x3f;
             m_pen.setWidth(deserializePenWidth(penWidth));
-            points.first = penWidth;
+            if(flags & 0x40)
+                m_pen.setBrush(m_eraser);
+            else
+                m_pen.setBrush(m_brush);
+            params.width = penWidth;
         }
 
-        points.second.append(QPoint(px, py));
+        params.points.append(QPoint(px, py));
     }
 
-    if(points.second.size())
+    if(params.points.size())
     {
-        addPath(pointsToPath(points.second), m_pen);
-        paths.prepend(points);
+        addPath(pointsToPath(params.points), m_pen);
+        paths.prepend(params);
     }
 
     emit pathChanged();
+
+    setErasing(erasing);
 }
 
 void DrawMapScene::simplifyLast()
 {
     if(!paths.size()) return;
 
-    QList<QPoint> points = paths.at(0).second;
+    QList<QPoint> points = paths.at(0).points;
 
     QPoint prevPoint = points.first();
     int i = 1;
@@ -248,13 +275,13 @@
         }
     }
 
-    paths[0].second = points;
+    paths[0].points = points;
 
 
     // redraw path
     {
         QGraphicsPathItem * pathItem = static_cast<QGraphicsPathItem *>(items()[0]);
-        pathItem->setPath(pointsToPath(paths[0].second));
+        pathItem->setPath(pointsToPath(paths[0].points));
     }
 
     emit pathChanged();
--- a/QTfrontend/drawmapscene.h	Mon Apr 09 22:01:13 2012 +0400
+++ b/QTfrontend/drawmapscene.h	Mon Apr 09 22:01:36 2012 +0400
@@ -24,7 +24,14 @@
 
 class QGraphicsPathItem;
 
-typedef QList<QPair<quint8, QList<QPoint> > > Paths;
+struct PathParams
+{
+    quint8 width;
+    bool erasing;
+    QList<QPoint> points;
+};
+
+typedef QList<PathParams> Paths;
 
 class DrawMapScene : public QGraphicsScene
 {
@@ -42,13 +49,16 @@
         void undo();
         void clearMap();
         void simplifyLast();
+        void setErasing(bool erasing);
 
     private:
         QPen m_pen;
+        QBrush m_eraser;
         QBrush m_brush;
         QGraphicsPathItem  * m_currPath;
         Paths paths;
         Paths oldPaths;
+        bool m_isErasing;
         QList<QGraphicsItem *> oldItems;
 
         virtual void mouseMoveEvent(QGraphicsSceneMouseEvent * mouseEvent);
--- a/QTfrontend/ui/page/pagedrawmap.cpp	Mon Apr 09 22:01:13 2012 +0400
+++ b/QTfrontend/ui/page/pagedrawmap.cpp	Mon Apr 09 22:01:36 2012 +0400
@@ -19,6 +19,7 @@
 #include <QGridLayout>
 #include <QPushButton>
 #include <QFileDialog>
+#include <QCheckBox>
 
 #include "pagedrawmap.h"
 #include "drawmapwidget.h"
@@ -28,19 +29,22 @@
 {
     QGridLayout * pageLayout = new QGridLayout();
 
-    pbUndo = addButton(tr("Undo"), pageLayout, 0, 0);
-    pbClear = addButton(tr("Clear"), pageLayout, 1, 0);
-    pbLoad = addButton(tr("Load"), pageLayout, 2, 0);
-    pbSave = addButton(tr("Save"), pageLayout, 3, 0);
+    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);
 
     drawMapWidget = new DrawMapWidget(this);
-    pageLayout->addWidget(drawMapWidget, 0, 1, 5, 1);
+    pageLayout->addWidget(drawMapWidget, 0, 1, 6, 1);
 
     return pageLayout;
 }
 
 void PageDrawMap::connectSignals()
 {
+    connect(cbEraser, SIGNAL(toggled(bool)), drawMapWidget, SLOT(setErasing(bool)));
     connect(pbUndo, SIGNAL(clicked()), drawMapWidget, SLOT(undo()));
     connect(pbClear, SIGNAL(clicked()), drawMapWidget, SLOT(clear()));
     connect(pbLoad, SIGNAL(clicked()), this, SLOT(load()));
--- a/QTfrontend/ui/page/pagedrawmap.h	Mon Apr 09 22:01:13 2012 +0400
+++ b/QTfrontend/ui/page/pagedrawmap.h	Mon Apr 09 22:01:36 2012 +0400
@@ -41,6 +41,7 @@
         QPushButton * pbClear;
         QPushButton * pbLoad;
         QPushButton * pbSave;
+        QCheckBox * cbEraser;
 
     private slots:
         void load();
--- a/QTfrontend/ui/widget/drawmapwidget.cpp	Mon Apr 09 22:01:13 2012 +0400
+++ b/QTfrontend/ui/widget/drawmapwidget.cpp	Mon Apr 09 22:01:36 2012 +0400
@@ -80,6 +80,11 @@
     if(m_scene) m_scene->clearMap();
 }
 
+void DrawMapWidget::setErasing(bool erasing)
+{
+    if(m_scene) m_scene->setErasing(erasing);
+}
+
 void DrawMapWidget::save(const QString & fileName)
 {
     if(m_scene)
--- a/QTfrontend/ui/widget/drawmapwidget.h	Mon Apr 09 22:01:13 2012 +0400
+++ b/QTfrontend/ui/widget/drawmapwidget.h	Mon Apr 09 22:01:36 2012 +0400
@@ -70,6 +70,7 @@
     public slots:
         void undo();
         void clear();
+        void setErasing(bool erasing);
         void save(const QString & fileName);
         void load(const QString & fileName);
 
--- a/hedgewars/pas2cSystem.pas	Mon Apr 09 22:01:13 2012 +0400
+++ b/hedgewars/pas2cSystem.pas	Mon Apr 09 22:01:36 2012 +0400
@@ -17,7 +17,6 @@
     Int = integer;
 
     pointer = pointer;
-    PChar = pointer;
 
     float = float;
     single = float;
@@ -36,6 +35,7 @@
     widechar = string;
 
     char = char;
+    PChar = ^char;
     
     PByte = ^Byte;
     PLongInt = ^LongInt;
--- a/hedgewars/uLandPainted.pas	Mon Apr 09 22:01:13 2012 +0400
+++ b/hedgewars/uLandPainted.pas	Mon Apr 09 22:01:36 2012 +0400
@@ -43,7 +43,7 @@
 
 var pointsListHead, pointsListLast: PPointEntry;
 
-procedure DrawLineOnLand(X1, Y1, X2, Y2, radius: LongInt);
+procedure DrawLineOnLand(X1, Y1, X2, Y2, radius: LongInt; color: Longword);
 var  eX, eY, dX, dY: LongInt;
     i, sX, sY, x, y, d: LongInt;
     b: boolean;
@@ -110,7 +110,7 @@
                 begin
                 inc(len);
                 if (len mod 4) = 0 then
-                    FillRoundInLand(X, Y, radius, lfBasic)
+                    FillRoundInLand(X, Y, radius, color)
                 end
         end
 end;
@@ -148,6 +148,7 @@
 var pe: PPointEntry;
     prevPoint: PointRec;
     radius: LongInt;
+    color: Longword;
 begin
     // shutup compiler
     prevPoint.X:= 0;
@@ -161,14 +162,18 @@
         begin
         if (pe^.point.flags and $80 <> 0) then
             begin
-            radius:= (pe^.point.flags and $7F) * 5 + 3;
-            AddFileLog('[DRAW] Move to: ('+inttostr(pe^.point.X)+','+inttostr(pe^.point.Y)+')');
-            FillRoundInLand(pe^.point.X, pe^.point.Y, radius, lfBasic)
+            if (pe^.point.flags and $40 <> 0) then
+                color:= 0
+                else
+                color:= lfBasic;
+            radius:= (pe^.point.flags and $3F) * 5 + 3;
+            AddFileLog('[DRAW] Move to: ('+inttostr(pe^.point.X)+','+inttostr(pe^.point.Y)+'), radius = '+inttostr(radius));
+            FillRoundInLand(pe^.point.X, pe^.point.Y, radius, color)
             end
             else
             begin
-            AddFileLog('[DRAW] Line to: ('+inttostr(pe^.point.X)+','+inttostr(pe^.point.Y)+')');
-            DrawLineOnLand(prevPoint.X, prevPoint.Y, pe^.point.X, pe^.point.Y, radius);
+            AddFileLog('[DRAW] Line to: ('+inttostr(pe^.point.X)+','+inttostr(pe^.point.Y)+'), radius = '+inttostr(radius));
+            DrawLineOnLand(prevPoint.X, prevPoint.Y, pe^.point.X, pe^.point.Y, radius, color);
             end;
 
         prevPoint:= pe^.point;