Skip to content

Commit

Permalink
Added option to render object names when exporting as image
Browse files Browse the repository at this point in the history
Closes #2216
  • Loading branch information
bjorn committed May 13, 2020
1 parent b26c29b commit 83c7953
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 39 deletions.
33 changes: 23 additions & 10 deletions src/libtiled/minimaprenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,11 @@ void MiniMapRenderer::renderToImage(QImage& image, RenderFlags renderFlags) cons
if (image.isNull())
return;

bool drawObjects = renderFlags.testFlag(RenderFlag::DrawMapObjects);
bool drawTileLayers = renderFlags.testFlag(RenderFlag::DrawTileLayers);
bool drawImageLayers = renderFlags.testFlag(RenderFlag::DrawImageLayers);
bool drawTileGrid = renderFlags.testFlag(RenderFlag::DrawGrid);
bool visibleLayersOnly = renderFlags.testFlag(RenderFlag::IgnoreInvisibleLayer);
const bool drawObjects = renderFlags.testFlag(RenderFlag::DrawMapObjects);
const bool drawTileLayers = renderFlags.testFlag(RenderFlag::DrawTileLayers);
const bool drawImageLayers = renderFlags.testFlag(RenderFlag::DrawImageLayers);
const bool drawTileGrid = renderFlags.testFlag(RenderFlag::DrawGrid);
const bool visibleLayersOnly = renderFlags.testFlag(RenderFlag::IgnoreInvisibleLayer);

QRect mapBoundingRect = mRenderer->mapBoundingRect();

Expand All @@ -164,8 +164,8 @@ void MiniMapRenderer::renderToImage(QImage& image, RenderFlags renderFlags) cons
mapSize.setHeight(mapSize.height() + margins.top() + margins.bottom());

// Determine the largest possible scale
qreal scale = qMin(static_cast<qreal>(image.width()) / mapSize.width(),
static_cast<qreal>(image.height()) / mapSize.height());
const qreal scale = qMin(static_cast<qreal>(image.width()) / mapSize.width(),
static_cast<qreal>(image.height()) / mapSize.height());

if (renderFlags.testFlag(DrawBackground) && mMap->backgroundColor().isValid())
image.fill(mMap->backgroundColor());
Expand All @@ -176,9 +176,9 @@ void MiniMapRenderer::renderToImage(QImage& image, RenderFlags renderFlags) cons
painter.setRenderHints(QPainter::SmoothPixmapTransform, renderFlags.testFlag(SmoothPixmapTransform));

// Center the map in the requested size
QSize scaledMapSize = mapSize * scale;
QPointF centerOffset((image.width() - scaledMapSize.width()) / 2,
(image.height() - scaledMapSize.height()) / 2);
const QSize scaledMapSize = mapSize * scale;
const QPointF centerOffset((image.width() - scaledMapSize.width()) / 2,
(image.height() - scaledMapSize.height()) / 2);

painter.translate(centerOffset);
painter.scale(scale, scale);
Expand Down Expand Up @@ -252,4 +252,17 @@ void MiniMapRenderer::renderToImage(QImage& image, RenderFlags renderFlags) cons

if (drawTileGrid)
mRenderer->drawGrid(&painter, mapBoundingRect, mGridColor);

if (drawObjects && mRenderObjectLabelCallback) {
for (const Layer *layer : mMap->objectGroups()) {
if (visibleLayersOnly && layer->isHidden())
continue;

const ObjectGroup *objectGroup = static_cast<const ObjectGroup*>(layer);

for (const MapObject *object : objectGroup->objects())
if (object->isVisible())
mRenderObjectLabelCallback(painter, object, *mRenderer);
}
}
}
12 changes: 12 additions & 0 deletions src/libtiled/minimaprenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,19 @@

#include <QImage>

#include <functional>

namespace Tiled {

class Map;
class MapObject;
class MapRenderer;

class TILEDSHARED_EXPORT MiniMapRenderer
{
public:
using RenderObjectLabelCallback = std::function<void(QPainter&, const MapObject*, const MapRenderer&)>;

enum RenderFlag {
DrawMapObjects = 0x0001,
DrawTileLayers = 0x0002,
Expand All @@ -59,6 +64,7 @@ class TILEDSHARED_EXPORT MiniMapRenderer
~MiniMapRenderer();

void setGridColor(const QColor &color);
void setRenderObjectLabelCallback(const RenderObjectLabelCallback &cb);

QSize mapSize() const;

Expand All @@ -74,6 +80,7 @@ class TILEDSHARED_EXPORT MiniMapRenderer
#else
QColor mGridColor = QColorConstants::Black;
#endif
RenderObjectLabelCallback mRenderObjectLabelCallback;
};


Expand All @@ -82,6 +89,11 @@ inline void MiniMapRenderer::setGridColor(const QColor &color)
mGridColor = color;
}

inline void MiniMapRenderer::setRenderObjectLabelCallback(const RenderObjectLabelCallback &cb)
{
mRenderObjectLabelCallback = cb;
}

} // namespace Tiled

Q_DECLARE_OPERATORS_FOR_FLAGS(Tiled::MiniMapRenderer::RenderFlags)
23 changes: 23 additions & 0 deletions src/tiled/exportasimagedialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "maprenderer.h"
#include "minimaprenderer.h"
#include "objectgroup.h"
#include "objectselectionitem.h"
#include "preferences.h"
#include "session.h"
#include "tilelayer.h"
Expand All @@ -44,6 +45,7 @@ namespace session {
static SessionOption<bool> visibleLayersOnly { "exportAsImage.visibleLayersOnly", true };
static SessionOption<bool> useCurrentScale { "exportAsImage.useCurrentScale", true };
static SessionOption<bool> drawTileGrid { "exportAsImage.drawTileGrid", false };
static SessionOption<bool> drawObjectLabels { "exportAsImage.drawObjectLabels", false };
static SessionOption<bool> includeBackgroundColor { "exportAsImage.includeBackgroundColor", false };
} // namespace session

Expand Down Expand Up @@ -92,6 +94,7 @@ ExportAsImageDialog::ExportAsImageDialog(MapDocument *mapDocument,
mUi->visibleLayersOnly->setChecked(session::visibleLayersOnly);
mUi->currentZoomLevel->setChecked(session::useCurrentScale);
mUi->drawTileGrid->setChecked(session::drawTileGrid);
mUi->drawObjectLabels->setChecked(session::drawObjectLabels);
mUi->includeBackgroundColor->setChecked(session::includeBackgroundColor);

connect(mUi->browseButton, &QAbstractButton::clicked, this, &ExportAsImageDialog::browse);
Expand Down Expand Up @@ -136,11 +139,31 @@ void ExportAsImageDialog::accept()
session::visibleLayersOnly = mUi->visibleLayersOnly->isChecked();
session::useCurrentScale = mUi->currentZoomLevel->isChecked();
session::drawTileGrid = mUi->drawTileGrid->isChecked();
session::drawObjectLabels = mUi->drawObjectLabels->isChecked();
session::includeBackgroundColor = mUi->includeBackgroundColor->isChecked();

MiniMapRenderer miniMapRenderer(mMapDocument->map());
miniMapRenderer.setGridColor(Preferences::instance()->gridColor());

if (session::drawObjectLabels) {
miniMapRenderer.setRenderObjectLabelCallback([] (QPainter &painter, const MapObject *object, const MapRenderer &renderer) {
if (object->name().isEmpty())
return;

MapObjectLabel label { object };
label.syncWithMapObject(renderer);

const auto invertScale = 1 / renderer.painterScale();
painter.save();
painter.translate(label.pos());
painter.scale(invertScale, invertScale);

label.paint(&painter, nullptr, nullptr);

painter.restore();
});
}

MiniMapRenderer::RenderFlags renderFlags(MiniMapRenderer::DrawTileLayers |
MiniMapRenderer::DrawMapObjects |
MiniMapRenderer::DrawImageLayers);
Expand Down
9 changes: 8 additions & 1 deletion src/tiled/exportasimagedialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>337</width>
<height>231</height>
<height>402</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -76,6 +76,13 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="drawObjectLabels">
<property name="text">
<string>Draw object &amp;names</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="includeBackgroundColor">
<property name="text">
Expand Down
35 changes: 8 additions & 27 deletions src/tiled/objectselectionitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,33 +145,14 @@ void MapObjectOutline::timerEvent(QTimerEvent *event)
}


class MapObjectLabel : public QGraphicsItem
MapObjectLabel::MapObjectLabel(const MapObject *object, QGraphicsItem *parent)
: QGraphicsItem(parent)
, mObject(object)
, mColor(mObject->effectiveColor())
{
public:
MapObjectLabel(MapObject *object, QGraphicsItem *parent = nullptr)
: QGraphicsItem(parent)
, mObject(object)
, mColor(mObject->effectiveColor())
{
setFlags(QGraphicsItem::ItemIgnoresTransformations |
QGraphicsItem::ItemIgnoresParentOpacity);
}

MapObject *mapObject() const { return mObject; }
void syncWithMapObject(const MapRenderer &renderer);
void updateColor();

QRectF boundingRect() const override;
void paint(QPainter *painter,
const QStyleOptionGraphicsItem *,
QWidget *) override;

private:
QRectF mBoundingRect;
QPointF mTextPos;
MapObject *mObject;
QColor mColor;
};
setFlags(QGraphicsItem::ItemIgnoresTransformations |
QGraphicsItem::ItemIgnoresParentOpacity);
}

void MapObjectLabel::syncWithMapObject(const MapRenderer &renderer)
{
Expand Down Expand Up @@ -611,7 +592,7 @@ void ObjectSelectionItem::tilesetTilePositioningChanged(Tileset *tileset)

void ObjectSelectionItem::tileTypeChanged(Tile *tile)
{
auto isObjectAffected = [tile] (MapObject *object) -> bool {
auto isObjectAffected = [tile] (const MapObject *object) -> bool {
if (!object->type().isEmpty())
return false;

Expand Down
23 changes: 22 additions & 1 deletion src/tiled/objectselectionitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,36 @@ namespace Tiled {
class GroupLayer;
class Layer;
class MapObject;
class MapRenderer;
class Tile;
class Tileset;

class MapDocument;
class MapObjectItem;
class MapObjectLabel;
class MapObjectOutline;
class ObjectReferenceItem;

class MapObjectLabel : public QGraphicsItem
{
public:
MapObjectLabel(const MapObject *object, QGraphicsItem *parent = nullptr);

const MapObject *mapObject() const { return mObject; }
void syncWithMapObject(const MapRenderer &renderer);
void updateColor();

QRectF boundingRect() const override;
void paint(QPainter *painter,
const QStyleOptionGraphicsItem *,
QWidget *) override;

private:
QRectF mBoundingRect;
QPointF mTextPos;
const MapObject *mObject;
QColor mColor;
};

/**
* A graphics item displaying object selection.
*
Expand Down

0 comments on commit 83c7953

Please sign in to comment.