-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Conversation
e9fef58
to
f19a5cc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thabetx Thank you so much for coming back to this! Overall your change looks very good. I've added a number of comments.
Usability wise, I think a minor improvement could be to mention the template name in the menu item, like Replace with "Rock" Template
in the case of your demonstration above.
src/tiled/abstractobjecttool.cpp
Outdated
{ | ||
mapDocument()->undoStack()->push(new ReplaceObjectsWithTemplate(mapDocument(), | ||
mapDocument()->selectedObjects(), | ||
{objectTemplate()->templateGroup(), objectTemplate()->id()})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the new templateRef
method you added here. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason I didn't commit that 😅.
src/tiled/abstracttool.cpp
Outdated
@@ -22,6 +22,7 @@ | |||
#include "abstracttool.h" | |||
|
|||
#include "mapdocument.h" | |||
#include "templatesdock.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't look like you need this include here?
src/tiled/changemapobject.cpp
Outdated
@@ -204,6 +204,20 @@ void DetachObjects::undo() | |||
emit mMapDocument->mapObjectModel()->objectsChanged(mMapObjects); | |||
} | |||
|
|||
void copyProperties(const MapObject *source, MapObject *target) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coding style: please place the {
on its own line for function definitions.
Please mark this function static
.
Could this potentially be implemented as MapObject::operator=(const MapObject &other)
, so it could be done like *target = *source
? Or does this have different semantics than assignment? At least having it in MapObject
would make it easier not to forget adding more things to it later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using the = operator looks like a good idea, it copies everything except id and position so I think i's okay but 'm not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I guess operator=
could be expected to copy those as well, so probably better to leave this as a special function.
src/tiled/changemapobject.cpp
Outdated
for (int i = 0; i < mMapObjects.size(); ++i) { | ||
MapObject *current = mMapObjects.at(i); | ||
MapObject *old = mOldMapObjects.at(i); | ||
copyProperties(old, current);; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove second ;
src/tiled/changemapobject.cpp
Outdated
|
||
|
||
ReplaceObjectsWithTemplate::ReplaceObjectsWithTemplate(MapDocument *mapDocument, | ||
const QList<MapObject *> &mapObjects, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation missing a space.
src/tiled/changemapobject.cpp
Outdated
} | ||
|
||
emit mMapDocument->objectsChanged(mMapObjects); | ||
emit mMapDocument->selectedObjectsChanged(); | ||
} | ||
|
||
ReplaceObjectsWithTemplate::~ReplaceObjectsWithTemplate() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please define the destructor right after the constructor (matching the order in the header file).
src/tiled/mapdocument.cpp
Outdated
@@ -139,7 +139,7 @@ void MapDocument::saveSelectedObject(const QString &name, int groupIndex) | |||
|
|||
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->setTemplateRef(objectTemplate->templateRef()); | |||
object->setChangedProperties(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually these lines should be covered by an undo command, right? Now that you've written ReplaceObjectsWithTemplate
, you should probably use it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, currently this would be a partial undo, as removing from the template group is not implemented. But at least it would reset the object to being a normal object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think partial undo would be fine here.
I like the option to add the name of the template in the context menu. It makes things clearer. |
src/tiled/changemapobject.cpp
Outdated
target->setShape(source->shape()); | ||
target->setCell(source->cell()); | ||
target->setRotation(source->rotation()); | ||
target->setVisible(source->VisibleProperty); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just noticed this little issue. I won't change it now on master to avoid conflicts, so please fix this to source->isVisible()
as part of this PR.
I cleaned the code and made some fixes and changes. Replacing was enabled for tile objects only, so I fixed that as well, but now when replacing a non-tile object e.g. a polygon with a template, Tiled will crash. I think the reason is that the two objects have different sets of properties and when the properties dock is asked to update it can't set the properties of the new object. So I will be looking into it and will do some more testing. |
Ah, you're right. This new Replace by Template action is the first action that allows changing the actual type of an object, and some properties are only created for certain objects (like flipping for tile objects, and width/height only for rectangles, tiles and ellipses). So the PropertyBrowser will need some changes for this. |
src/tiled/abstractobjecttool.cpp
Outdated
auto replaceTemplateAction = menu.addAction(tr("Replace With Template"), this, SLOT(replaceObjectsWithTemplate())); | ||
|
||
if (selectedTemplate) | ||
replaceTemplateAction->setText(tr("Replace With \"") + selectedTemplate->name() + tr("\" Template")); |
There was a problem hiding this comment.
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())
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright.
Conflicts: src/libtiled/objecttemplate.h src/tiled/createtemplatetool.cpp src/tiled/mapdocument.cpp src/tiled/mapscene.cpp
Alright, I've merged The remaining issue is the crashing when changing the kind of object through replacing it with a template. |
By replacing an object with a template, it is possible to change whether it has dimensions, or whether it is a tile or a text object. This affects which properties should be listed. The easiest way to adjust the list of properties is to refresh it entirely when necessary.
Hello bjron, thank you for the updates, I was stuck at updating the properties and the custom properties. I tested it and it's working great. I will try working on #1823 . Again thank you :). |
No problem, I just needed this to be finished since I'm trying to move forward with a 1.1 release, which means finishing up the loose ends.
Ah, I was about to look into it myself too, especially since I introduced this one recently, but feel free to have a look into it. It's probably not a hard one to fix. |
Okay you can continue looking into it, I will try improving broken links. Undoing after fixing doesn't reset and I will also look into fixing broken tileset link inside the template #1732 . |
Solves #1722
Works exactly like the replace tile feature.
I had to move the selected template from the template creation tool into the tool manager so it can be used across all the tools, just like the tile.