Browse code

add support for ellipse game objects

devnewton authored on 17/06/2012 19:06:28
Showing 13 changed files
... ...
@@ -96,6 +96,7 @@ QPainterPath IsometricRenderer::shape(const MapObject *object) const
96 96
         path.addRect(boundingRect(object));
97 97
     } else {
98 98
         switch (object->shape()) {
99
+        case MapObject::Ellipse:
99 100
         case MapObject::Rectangle:
100 101
             path.addPolygon(tileRectToPolygon(object->bounds()));
101 102
             break;
... ...
@@ -343,6 +344,7 @@ void IsometricRenderer::drawMapObject(QPainter *painter,
343 344
         // TODO: Do something sensible to make null-sized objects usable
344 345
 
345 346
         switch (object->shape()) {
347
+        case MapObject::Ellipse:
346 348
         case MapObject::Rectangle: {
347 349
 
348 350
             QPointF topLeft(tileToPixelCoords(object->bounds().topLeft()));
... ...
@@ -63,7 +63,8 @@ public:
63 63
     enum Shape {
64 64
         Rectangle,
65 65
         Polygon,
66
-        Polyline
66
+        Polyline,
67
+        Ellipse
67 68
     };
68 69
 
69 70
     /**
... ...
@@ -186,7 +186,7 @@ bool MapReaderPrivate::openFile(QFile *file)
186 186
 
187 187
 void MapReaderPrivate::readUnknownElement()
188 188
 {
189
-    qDebug() << "Unknown element (fixme):" << xml.name();
189
+    qDebug() << "Unknown element (fixme):" << xml.name() << " at line " << xml.lineNumber() << ", column " << xml.columnNumber();
190 190
     xml.skipCurrentElement();
191 191
 }
192 192
 
... ...
@@ -739,6 +739,9 @@ MapObject *MapReaderPrivate::readObject()
739 739
         } else if (xml.name() == "polyline") {
740 740
             object->setPolygon(readPolygon());
741 741
             object->setShape(MapObject::Polyline);
742
+        } else if (xml.name() == "ellipse") {
743
+            xml.skipCurrentElement();
744
+            object->setShape(MapObject::Ellipse);
742 745
         } else {
743 746
             readUnknownElement();
744 747
         }
... ...
@@ -534,6 +534,9 @@ void MapWriterPrivate::writeObject(QXmlStreamWriter &w,
534 534
         w.writeEndElement();
535 535
     }
536 536
 
537
+    if(mapObject->shape() == MapObject::Ellipse)
538
+        w.writeEmptyElement(QLatin1String("ellipse"));
539
+
537 540
     w.writeEndElement();
538 541
 }
539 542
 
... ...
@@ -74,6 +74,7 @@ QRectF OrthogonalRenderer::boundingRect(const MapObject *object) const
74 74
     } else {
75 75
         // The -2 and +3 are to account for the pen width and shadow
76 76
         switch (object->shape()) {
77
+        case MapObject::Ellipse:
77 78
         case MapObject::Rectangle:
78 79
             if (rect.isNull()) {
79 80
                 boundingRect = rect.adjusted(-10 - 2, -10 - 2, 10 + 3, 10 + 3);
... ...
@@ -133,6 +134,18 @@ QPainterPath OrthogonalRenderer::shape(const MapObject *object) const
133 134
             }
134 135
             break;
135 136
         }
137
+        case MapObject::Ellipse: {
138
+            const QRectF bounds = object->bounds();
139
+            const QRectF rect(tileToPixelCoords(bounds.topLeft()),
140
+                              tileToPixelCoords(bounds.bottomRight()));
141
+
142
+            if (rect.isNull()) {
143
+                path.addEllipse(rect.topLeft(), 2, 2);
144
+            } else {
145
+                path.addEllipse(rect);
146
+            }
147
+            break;
148
+        }
136 149
         }
137 150
     }
138 151
 
... ...
@@ -366,6 +379,29 @@ void OrthogonalRenderer::drawMapObject(QPainter *painter,
366 379
             painter->drawPolygon(screenPolygon);
367 380
             break;
368 381
         }
382
+
383
+        case MapObject::Ellipse: {
384
+            if (rect.isNull())
385
+                rect = QRectF(QPointF(-10, -10), QSizeF(20, 20));
386
+
387
+            const QFontMetrics fm = painter->fontMetrics();
388
+            QString name = fm.elidedText(object->name(), Qt::ElideRight,
389
+                                         rect.width() + 2);
390
+
391
+            // Draw the shadow
392
+            painter->setPen(shadowPen);
393
+            painter->drawEllipse(rect.translated(QPointF(1, 1)));
394
+            if (!name.isEmpty())
395
+                painter->drawText(QPoint(1, -5 + 1), name);
396
+
397
+            painter->setPen(linePen);
398
+            painter->setBrush(fillBrush);
399
+            painter->drawEllipse(rect);
400
+            if (!name.isEmpty())
401
+                painter->drawText(QPoint(0, -5), name);
402
+
403
+            break;
404
+        }
369 405
         }
370 406
     }
371 407
 
... ...
@@ -226,6 +226,9 @@ QVariant MapToVariantConverter::toVariant(const ObjectGroup *objectGroup)
226 226
                 objectVariant["polyline"] = pointVariants;
227 227
         }
228 228
 
229
+        if(object->shape() == MapObject::Ellipse)
230
+            objectVariant["ellipse"] = true;
231
+
229 232
         objectVariants << objectVariant;
230 233
     }
231 234
 
... ...
@@ -299,6 +299,8 @@ ObjectGroup *VariantToMapConverter::toObjectGroup(const QVariantMap &variantMap)
299 299
             object->setShape(MapObject::Polyline);
300 300
             object->setPolygon(toPolygon(polylineVariant));
301 301
         }
302
+        if(objectVariantMap.contains("ellipse"))
303
+            object->setShape(MapObject::Ellipse);
302 304
     }
303 305
 
304 306
     return objectGroup;
... ...
@@ -78,6 +78,14 @@ CreateObjectTool::CreateObjectTool(CreationMode mode, QObject *parent)
78 78
         mOverlayObjectGroup->setColor(highlight);
79 79
         break;
80 80
     }
81
+    case CreateEllipse:
82
+        setIcon(QIcon(QLatin1String(":images/24x24/insert-ellipse.png")));
83
+        Utils::setThemeIcon(this, "insert-ellipse");
84
+        break;
85
+    case CreateCircle:
86
+        setIcon(QIcon(QLatin1String(":images/24x24/insert-circle.png")));
87
+        Utils::setThemeIcon(this, "insert-circle");
88
+        break;
81 89
     }
82 90
 
83 91
     languageChanged();
... ...
@@ -115,7 +123,22 @@ void CreateObjectTool::mouseMoved(const QPointF &pos,
115 123
         snapToGrid = !snapToGrid;
116 124
 
117 125
     switch (mMode) {
118
-    case CreateArea: {
126
+    case CreateArea:
127
+    case CreateEllipse: {
128
+        const QPointF tileCoords = renderer->pixelToTileCoords(pos);
129
+
130
+        // Update the size of the new map object
131
+        const QPointF objectPos = mNewMapObjectItem->mapObject()->position();
132
+        QSizeF newSize(qMax(qreal(0), tileCoords.x() - objectPos.x()),
133
+                       qMax(qreal(0), tileCoords.y() - objectPos.y()));
134
+
135
+        if (snapToGrid)
136
+            newSize = newSize.toSize();
137
+
138
+        mNewMapObjectItem->resize(newSize);
139
+        break;
140
+    }
141
+    case CreateCircle: {
119 142
         const QPointF tileCoords = renderer->pixelToTileCoords(pos);
120 143
 
121 144
         // Update the size of the new map object
... ...
@@ -126,6 +149,10 @@ void CreateObjectTool::mouseMoved(const QPointF &pos,
126 149
         if (snapToGrid)
127 150
             newSize = newSize.toSize();
128 151
 
152
+        float maxCoord = qMax(newSize.width(), newSize.height());
153
+        newSize.setWidth(maxCoord);
154
+        newSize.setHeight(maxCoord);
155
+
129 156
         mNewMapObjectItem->resize(newSize);
130 157
         break;
131 158
     }
... ...
@@ -165,6 +192,8 @@ void CreateObjectTool::mousePressed(QGraphicsSceneMouseEvent *event)
165 192
         switch (mMode) {
166 193
         case CreateArea:
167 194
         case CreateTile:
195
+        case CreateEllipse:
196
+        case CreateCircle:
168 197
             if (event->button() == Qt::RightButton)
169 198
                 cancelNewMapObject();
170 199
             break;
... ...
@@ -233,7 +262,7 @@ void CreateObjectTool::mousePressed(QGraphicsSceneMouseEvent *event)
233 262
 void CreateObjectTool::mouseReleased(QGraphicsSceneMouseEvent *event)
234 263
 {
235 264
     if (event->button() == Qt::LeftButton && mNewMapObjectItem) {
236
-        if (mMode == CreateArea || mMode == CreateTile)
265
+        if (mMode == CreateArea || mMode == CreateTile || mMode == CreateEllipse || mMode == CreateCircle)
237 266
             finishNewMapObject();
238 267
     }
239 268
 }
... ...
@@ -245,6 +274,14 @@ void CreateObjectTool::languageChanged()
245 274
         setName(tr("Insert Object"));
246 275
         setShortcut(QKeySequence(tr("O")));
247 276
         break;
277
+    case CreateCircle:
278
+        setName(tr("Insert Circle"));
279
+        setShortcut(QKeySequence(tr("C")));
280
+        break;
281
+    case CreateEllipse:
282
+        setName(tr("Insert Ellipse"));
283
+        setShortcut(QKeySequence(tr("E")));
284
+        break;
248 285
     case CreateTile:
249 286
         setName(tr("Insert Tile"));
250 287
         setShortcut(QKeySequence(tr("T")));
... ...
@@ -292,6 +329,9 @@ void CreateObjectTool::startNewMapObject(const QPointF &pos,
292 329
         mapScene()->addItem(mOverlayPolygonItem);
293 330
     }
294 331
 
332
+    if(mMode == CreateEllipse || mMode == CreateCircle)
333
+        newMapObject->setShape(MapObject::Ellipse);
334
+
295 335
     objectGroup->addObject(newMapObject);
296 336
 
297 337
     mNewMapObjectItem = new MapObjectItem(newMapObject, mapDocument());
... ...
@@ -40,7 +40,9 @@ public:
40 40
         CreateArea,
41 41
         CreateTile,
42 42
         CreatePolygon,
43
-        CreatePolyline
43
+        CreatePolyline,
44
+        CreateEllipse,
45
+        CreateCircle
44 46
     };
45 47
 
46 48
     CreateObjectTool(CreationMode mode, QObject *parent = 0);
47 49
new file mode 100644
48 50
Binary files /dev/null and b/src/tiled/images/24x24/insert-circle.png differ
49 51
new file mode 100644
50 52
Binary files /dev/null and b/src/tiled/images/24x24/insert-ellipse.png differ
... ...
@@ -335,6 +335,10 @@ MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
335 335
             CreateObjectTool::CreateTile, this);
336 336
     CreateObjectTool *areaObjectsTool = new CreateObjectTool(
337 337
             CreateObjectTool::CreateArea, this);
338
+    CreateObjectTool *circleObjectsTool = new CreateObjectTool(
339
+            CreateObjectTool::CreateCircle, this);
340
+    CreateObjectTool *ellipseObjectsTool = new CreateObjectTool(
341
+            CreateObjectTool::CreateEllipse, this);
338 342
     CreateObjectTool *polygonObjectsTool = new CreateObjectTool(
339 343
             CreateObjectTool::CreatePolygon, this);
340 344
     CreateObjectTool *polylineObjectsTool = new CreateObjectTool(
... ...
@@ -365,6 +369,8 @@ MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
365 369
     toolManager->registerTool(new ObjectSelectionTool(this));
366 370
     toolManager->registerTool(new EditPolygonTool(this));
367 371
     toolManager->registerTool(areaObjectsTool);
372
+    toolManager->registerTool(circleObjectsTool);
373
+    toolManager->registerTool(ellipseObjectsTool);
368 374
     toolManager->registerTool(tileObjectsTool);
369 375
     toolManager->registerTool(polygonObjectsTool);
370 376
     toolManager->registerTool(polylineObjectsTool);
... ...
@@ -57,6 +57,8 @@
57 57
         <file>images/24x24/insert-object.png</file>
58 58
         <file>images/24x24/insert-polygon.png</file>
59 59
         <file>images/24x24/insert-polyline.png</file>
60
+        <file>images/24x24/insert-ellipse.png</file>
61
+        <file>images/24x24/insert-circle.png</file>
60 62
         <file>images/24x24/zoom-in.png</file>
61 63
         <file>images/24x24/zoom-original.png</file>
62 64
         <file>images/24x24/zoom-out.png</file>