Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable replacing an object with a template #1793

Merged
merged 5 commits into from
Nov 29, 2017
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/libtiled/mapobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,22 @@ MapObject *MapObject::clone() const
return o;
}

void MapObject::copyPropertiesFrom(const MapObject *object)
{
setName(object->name());
setSize(object->size());
setType(object->type());
setTextData(object->textData());
setPolygon(object->polygon());
setShape(object->shape());
setCell(object->cell());
setRotation(object->rotation());
setVisible(object->isVisible());
setProperties(object->properties());
setChangedProperties(object->changedProperties());
setTemplateRef(object->templateRef());
}

const MapObject *MapObject::templateObject() const
{
if (auto group = templateGroup())
Expand Down
1 change: 1 addition & 0 deletions src/libtiled/mapobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ class TILEDSHARED_EXPORT MapObject : public Object
void flip(FlipDirection direction, const QPointF &origin);

MapObject *clone() const;
void copyPropertiesFrom(const MapObject *object);

const MapObject *templateObject() const;

Expand Down
6 changes: 6 additions & 0 deletions src/libtiled/objecttemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class TILEDSHARED_EXPORT ObjectTemplate : public Object
TemplateGroup *templateGroup() const;
void setTemplateGroup(TemplateGroup *templateGroup);

TemplateRef templateRef() const;

private:
MapObject *mObject;
unsigned mId;
Expand All @@ -68,6 +70,7 @@ inline void ObjectTemplate::setObject(const MapObject *object)
{
delete mObject;
mObject = object->clone();
mObject->setTemplateRef(templateRef());
mObject->markAsTemplateBase();
}

Expand All @@ -89,4 +92,7 @@ inline TemplateGroup *ObjectTemplate::templateGroup() const
inline void ObjectTemplate::setTemplateGroup(TemplateGroup *templateGroup)
{ mTemplateGroup = templateGroup; }

inline TemplateRef ObjectTemplate::templateRef() const
{ return TemplateRef {mTemplateGroup, mId}; }

} // namespace Tiled
18 changes: 18 additions & 0 deletions src/tiled/abstractobjecttool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,13 @@ void AbstractObjectTool::detachSelectedObjects()
currentMapDocument->undoStack()->push(changeMapObjectCommand);
}

void AbstractObjectTool::replaceObjectsWithTemplate()
{
mapDocument()->undoStack()->push(new ReplaceObjectsWithTemplate(mapDocument(),
mapDocument()->selectedObjects(),
objectTemplate()));
}

void AbstractObjectTool::resetInstances()
{
QList<MapObject *> templateInstances;
Expand Down Expand Up @@ -353,8 +360,18 @@ void AbstractObjectTool::showContextMenu(MapObjectItem *clickedObjectItem,
changeTileAction->setEnabled(tile());
}

// Create action for replacing an object with a template
auto selectedTemplate = objectTemplate();
auto replaceTemplateAction = menu.addAction(tr("Replace With Template"), this, SLOT(replaceObjectsWithTemplate()));

if (selectedTemplate)
replaceTemplateAction->setText(tr("Replace With \"") + selectedTemplate->name() + tr("\" Template"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not nice for the translator. You should instead use a parameter, like so:

tr("Replace With \"%1\" Template").arg(selectedTemplate->name())

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright.

else
replaceTemplateAction->setEnabled(false);

if (selectedObjects.size() == 1) {
MapObject *currentObject = selectedObjects.first();

if (!(currentObject->isTemplateBase() || currentObject->isTemplateInstance())) {
const Cell cell = selectedObjects.first()->cell();
// Saving objects with embedded tilesets is disabled
Expand All @@ -365,6 +382,7 @@ void AbstractObjectTool::showContextMenu(MapObjectItem *clickedObjectItem,
if (currentObject->isTemplateBase()) { // Hide this operations for template base
duplicateAction->setVisible(false);
removeAction->setVisible(false);
replaceTemplateAction->setVisible(false);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/tiled/abstractobjecttool.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ private slots:
void resetTileSize();
void saveSelectedObject();
void detachSelectedObjects();
void replaceObjectsWithTemplate();
void resetInstances();
void changeTile();

Expand Down
1 change: 1 addition & 0 deletions src/tiled/abstracttool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ AbstractTool::AbstractTool(const QString &name, const QIcon &icon,
, mShortcut(shortcut)
, mEnabled(false)
, mTile(nullptr)
, mObjectTemplate(nullptr)
, mMapDocument(nullptr)
{
}
Expand Down
15 changes: 15 additions & 0 deletions src/tiled/abstracttool.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace Tiled {

class Layer;
class Tile;
class ObjectTemplate;

namespace Internal {

Expand Down Expand Up @@ -94,6 +95,8 @@ class AbstractTool : public QObject

Tile *tile() const;

ObjectTemplate *objectTemplate() const;

/**
* Activates this tool. If the tool plans to add any items to the scene, it
* probably wants to do it here.
Expand Down Expand Up @@ -152,6 +155,7 @@ class AbstractTool : public QObject
public slots:
void setMapDocument(MapDocument *mapDocument);
void setTile(Tile *tile);
void setObjectTemplate(ObjectTemplate *objectTemplate);

protected:
/**
Expand Down Expand Up @@ -191,6 +195,7 @@ protected slots:
QCursor mCursor;
bool mEnabled;
Tile *mTile;
ObjectTemplate *mObjectTemplate;

MapDocument *mMapDocument;
};
Expand Down Expand Up @@ -251,6 +256,16 @@ inline void AbstractTool::setTile(Tile *tile)
mTile = tile;
}

inline ObjectTemplate *AbstractTool::objectTemplate() const
{
return mObjectTemplate;
}

inline void AbstractTool::setObjectTemplate(ObjectTemplate *objectTemplate)
{
mObjectTemplate = objectTemplate;
}

} // namespace Internal
} // namespace Tiled

Expand Down
61 changes: 45 additions & 16 deletions src/tiled/changemapobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "mapdocument.h"
#include "mapobjectmodel.h"
#include "objecttemplate.h"

#include <QCoreApplication>

Expand Down Expand Up @@ -204,7 +205,6 @@ void DetachObjects::undo()
emit mMapDocument->mapObjectModel()->objectsChanged(mMapObjects);
}


ResetInstances::ResetInstances(MapDocument *mapDocument,
const QList<MapObject *> &mapObjects,
QUndoCommand *parent)
Expand Down Expand Up @@ -242,21 +242,50 @@ void ResetInstances::redo()

void ResetInstances::undo()
{
for (int i = 0; i < mMapObjects.size(); ++i) {
MapObject *current = mMapObjects.at(i);
MapObject *old = mOldMapObjects.at(i);
current->setName(old->name());
current->setSize(old->size());
current->setType(old->type());
current->setTextData(old->textData());
current->setPolygon(old->polygon());
current->setShape(old->shape());
current->setCell(old->cell());
current->setRotation(old->rotation());
current->setVisible(old->VisibleProperty);
current->setProperties(old->properties());
current->setChangedProperties(old->changedProperties());
}
for (int i = 0; i < mMapObjects.size(); ++i)
mMapObjects.at(i)->copyPropertiesFrom(mOldMapObjects.at(i));

emit mMapDocument->objectsChanged(mMapObjects);
emit mMapDocument->selectedObjectsChanged();
}


ReplaceObjectsWithTemplate::ReplaceObjectsWithTemplate(MapDocument *mapDocument,
const QList<MapObject *> &mapObjects,
ObjectTemplate *objectTemplate,
QUndoCommand *parent)
: QUndoCommand(QCoreApplication::translate("Undo Commands",
"Replace %n object(s) with template",
nullptr, mapObjects.size()), parent)
, mMapDocument(mapDocument)
, mMapObjects(mapObjects)
, mObjectTemplate(objectTemplate)
{
for (const MapObject *object : mapObjects)
mOldMapObjects.append(object->clone());
}

ReplaceObjectsWithTemplate::~ReplaceObjectsWithTemplate()
{
qDeleteAll(mOldMapObjects);
}


void ReplaceObjectsWithTemplate::redo()
{
auto newMapObject = mObjectTemplate->object();
for (auto object : mMapObjects)
object->copyPropertiesFrom(newMapObject);

// Critical bug here
emit mMapDocument->objectsChanged(mMapObjects);
emit mMapDocument->selectedObjectsChanged();
}

void ReplaceObjectsWithTemplate::undo()
{
for (int i = 0; i < mMapObjects.size(); ++i)
mMapObjects.at(i)->copyPropertiesFrom(mOldMapObjects.at(i));

emit mMapDocument->objectsChanged(mMapObjects);
emit mMapDocument->selectedObjectsChanged();
Expand Down
24 changes: 24 additions & 0 deletions src/tiled/changemapobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
namespace Tiled {

class MapObject;
class ObjectTemplate;
class Tile;

namespace Internal {
Expand Down Expand Up @@ -150,5 +151,28 @@ class ResetInstances : public QUndoCommand
QList<MapObject*> mOldMapObjects;
};

class ReplaceObjectsWithTemplate : public QUndoCommand
{
public:
/**
* Creates an undo command that replaces the given objects with a template
*/
ReplaceObjectsWithTemplate(MapDocument *mapDocument,
const QList<MapObject *> &mapObjects,
ObjectTemplate *objectTemplate,
QUndoCommand *parent = nullptr);

~ReplaceObjectsWithTemplate();

void redo() override;
void undo() override;

private:
MapDocument *mMapDocument;
const QList<MapObject*> mMapObjects;
QList<MapObject*> mOldMapObjects;
ObjectTemplate *mObjectTemplate;
};

} // namespace Internal
} // namespace Tiled
7 changes: 4 additions & 3 deletions src/tiled/createtemplatetool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ using namespace Tiled::Internal;

CreateTemplateTool::CreateTemplateTool(QObject *parent)
: CreateObjectTool(parent)
, mObjectTemplate(nullptr)
{
QIcon icon(QLatin1String(":images/24x24/insert-template.png"));
icon.addFile(QLatin1String(":images/48x48/insert-template.png"));
Expand Down Expand Up @@ -86,11 +85,13 @@ void CreateTemplateTool::languageChanged()

MapObject *CreateTemplateTool::createNewMapObject()
{
if (!mObjectTemplate)
auto newObjectTemplate = objectTemplate();

if (!newObjectTemplate)
return nullptr;

MapObject *newMapObject = new MapObject();
newMapObject->setTemplateRef({mObjectTemplate->templateGroup(), mObjectTemplate->id()});
newMapObject->setTemplateRef(newObjectTemplate->templateRef());
newMapObject->syncWithTemplate();
return newMapObject;
}
6 changes: 0 additions & 6 deletions src/tiled/createtemplatetool.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ class CreateTemplateTool : public CreateObjectTool

void languageChanged() override;

public slots:
void setTemplate(ObjectTemplate *objectTemplate) { mObjectTemplate = objectTemplate; }

protected:
void mouseMovedWhileCreatingObject(const QPointF &pos,
Qt::KeyboardModifiers modifiers) override;
Expand All @@ -49,9 +46,6 @@ public slots:

bool startNewMapObject(const QPointF &pos, ObjectGroup *objectGroup) override;
MapObject *createNewMapObject() override;

private:
ObjectTemplate *mObjectTemplate;
};

} // namespace Internal
Expand Down
8 changes: 2 additions & 6 deletions src/tiled/mapdocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,8 @@ void MapDocument::saveSelectedObject(const QString &name, int groupIndex)
ObjectTemplateModel* model = ObjectTemplateModel::instance();
MapObject *object = mSelectedObjects.first();

if (ObjectTemplate *objectTemplate = model->saveObjectToDocument(object, name, groupIndex)) {
// Convert the saved object into an instance and clear the changed properties flags
object->setTemplateRef({objectTemplate->templateGroup(), objectTemplate->id()});
object->setChangedProperties(0);
emit objectsChanged(mSelectedObjects);
}
if (ObjectTemplate *objectTemplate = model->saveObjectToDocument(object, name, groupIndex))
undoStack()->push(new ReplaceObjectsWithTemplate(this, mSelectedObjects, objectTemplate));
}

bool MapDocument::save(const QString &fileName, QString *error)
Expand Down
2 changes: 1 addition & 1 deletion src/tiled/mapeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ MapEditor::MapEditor(QObject *parent)
connect(mTilesetDock, &TilesetDock::currentTileChanged, mTemplatesDock, &TemplatesDock::setTile);
connect(mTilesetDock, &TilesetDock::stampCaptured, this, &MapEditor::setStamp);
connect(mTilesetDock, &TilesetDock::localFilesDropped, this, &MapEditor::filesDroppedOnTilesetDock);
connect(mTemplatesDock, &TemplatesDock::currentTemplateChanged, templatesTool, &CreateTemplateTool::setTemplate);
connect(mTemplatesDock, &TemplatesDock::currentTemplateChanged, mToolManager, &ToolManager::setObjectTemplate);

connect(mStampBrush, &StampBrush::stampChanged, this, &MapEditor::setStamp);
connect(mBucketFillTool, &BucketFillTool::stampChanged, this, &MapEditor::setStamp);
Expand Down
2 changes: 1 addition & 1 deletion src/tiled/mapscene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ void MapScene::dropEvent(QGraphicsSceneDragDropEvent *event)
return;

MapObject *newMapObject = new MapObject();
newMapObject->setTemplateRef({objectTemplate->templateGroup(), objectTemplate->id()});
newMapObject->setTemplateRef(objectTemplate->templateRef());
newMapObject->syncWithTemplate();
newMapObject->setPosition(event->scenePos());

Expand Down
9 changes: 9 additions & 0 deletions src/tiled/toolmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ ToolManager::ToolManager(QObject *parent)
, mPreviouslyDisabledTool(nullptr)
, mMapDocument(nullptr)
, mTile(nullptr)
, mObjectTemplate(nullptr)
, mSelectEnabledToolPending(false)
{
mActionGroup->setExclusive(true);
Expand Down Expand Up @@ -186,6 +187,13 @@ void ToolManager::setTile(Tile *tile)
mSelectedTool->setTile(mTile);
}

void ToolManager::setObjectTemplate(ObjectTemplate *objectTemplate)
{
mObjectTemplate = objectTemplate;
if (mSelectedTool)
mSelectedTool->setObjectTemplate(mObjectTemplate);
}

void ToolManager::toolEnabledChanged(bool enabled)
{
AbstractTool *tool = qobject_cast<AbstractTool*>(sender());
Expand Down Expand Up @@ -261,5 +269,6 @@ void ToolManager::setSelectedTool(AbstractTool *tool)
connect(mSelectedTool, SIGNAL(statusInfoChanged(QString)),
this, SIGNAL(statusInfoChanged(QString)));
tool->setTile(mTile);
tool->setObjectTemplate(mObjectTemplate);
}
}
Loading