Skip to content
New issue

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

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

Already on GitHub? # to your account

Creating template instances #1652

Merged
merged 4 commits into from
Jul 25, 2017
Merged

Conversation

thabetx
Copy link
Contributor

@thabetx thabetx commented Jul 14, 2017

This pull request is part of the Reusable Object Templates project.

Added a template instance creation tool similar to the insert tile object tool. Also enabled dragging and dropping from the template dock into the map.

Right now, the functionality of the project can be tested without the need of manually editing files.

Copy link
Member

@bjorn bjorn left a comment

Choose a reason for hiding this comment

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

Some review feedback.

@@ -53,6 +53,11 @@ class ObjectTemplateModel : public QAbstractItemModel
bool addNewDocument(TemplateGroupDocument *document);
bool addTemplateGroup(TemplateGroup *templateGroup);
bool saveObjectToDocument(MapObject *object, QString name, int documentIndex);
ObjectTemplate *toObjectTemplate(const QModelIndex &index) const;

Qt::ItemFlags flags(const QModelIndex &index) const;
Copy link
Member

Choose a reason for hiding this comment

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

Should be marked as override.

void MapScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
event->ignore();
Q_UNUSED(event);
Copy link
Member

Choose a reason for hiding this comment

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

This function will still need to explicitly ignore the event when it does not contain the TEMPLATES_MIMETYPE, to make sure that maps and tilesets dropped on Tiled will get opened (also when dropped on the map view). I guess the comment you removed could have been more explicit about this. :-)

stream >> groupFileName >> templateId;

TemplateGroup *group = templateManager->findTemplateGroup(groupFileName);
const ObjectTemplate *objectTemplate = group->findTemplate(templateId);;
Copy link
Member

Choose a reason for hiding this comment

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

Please check both the group and the objectTemplate pointers, because you can't assume they will be valid. The dropped data could potentially come from another application, or just another instance of Tiled that hasn't got the same template groups loaded.


setSelectionMode(QAbstractItemView::SingleSelection);
setDragEnabled(true);
setDropIndicatorShown(true);
Copy link
Member

Choose a reason for hiding this comment

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

That seems a little pointless for a drag-only view, but I guess it could be enabled when we would later enable dragging templates from one group to another (which I think could be a good reason to try using UUIDs for template references).

TemplatesView::TemplatesView(QWidget *parent)
: QTreeView(parent)
{
setUniformRowHeights(true);
setHeaderHidden(true);

connect(this, SIGNAL(pressed(QModelIndex)), SLOT(onPressed(QModelIndex)));
Copy link
Member

Choose a reason for hiding this comment

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

For new connections, please prefer the modern connect syntax:

connect(this, &QAbstractItemView::pressed, this, &TemplatesView::onPressed);

Qt Creator has a fixup for doing the conversion when you put your cursor on it and press Ctrl+Enter (or right-click and choose "Refactor").

@@ -43,6 +45,8 @@ class TemplatesDock : public QDockWidget
TemplatesDock(QWidget *parent = nullptr);
~TemplatesDock();

TemplatesView *templatesView() const;
Copy link
Member

Choose a reason for hiding this comment

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

Instead of exposing the templates view, I would suggest to add the currentTemplateChanged signal also to the dock.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In that case the view emits the change then the dock emits it again, right?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, you can directly connect one signal to another signal to achieve this.

{
const MapRenderer *renderer = mapDocument()->renderer();

const QSize imgSize = mNewMapObjectItem->mapObject()->cell().tile()->size();
Copy link
Member

Choose a reason for hiding this comment

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

This crashed for me on the first try, because it assumes the object is a tile object and that its tile is loaded. I think it does make sense to center the object on the mouse, but doing this in the general case will be a little more complicated. You can try starting with using MapRenderer::boundingRect, which should do the trick for all non-rotated objects on non-isometric maps.

Centering correctly on isometric maps will unfortunately require handling tile objects and other objects differently.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have a tendency to test only tile objects and forget about the others.

I tried using the bounding rectangle dimensions to calculate the shift instead of the tile, but when clicking, each type has a different starting point, the tile objects uses the bottom left, ellipses, rectangles and text objects will use the top left, while a polyline or a polygon will use their first point.

The easy solution would be just use pos without any shifting. but I think we can handle them to always be centered using the bounding rectangle but with different shift for each type. Drag and drop uses the default starting point so it might be changed as well to be centered.

Copy link
Member

Choose a reason for hiding this comment

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

I think it will be fine for now to not bother with the centering at all. On the upside, it will give a clear indication to the user as to where the object is actually positioned, which will be beneficial also when this anchor point eventually becomes configurable.


void Map::removeTemplateGroupReference(const TemplateGroup *templateGroup)
{
// mTemplateGroupReferences[templateGroup]--;
Copy link
Member

Choose a reason for hiding this comment

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

Did this not work for some reason?

Btw, while it makes sense to automatically remove template group references, this is only relevant when saving the map. So rather than keeping reference counts, the map writer could also just iterate over all the objects to determine the list of template group references that need to be written. I would prefer that approach.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It worked fine but I wasn't sure which style to use. I will try the suggested approach it should be simpler.

@@ -74,6 +76,7 @@ public slots:
MapObjectItem *mNewMapObjectItem;
MapObjectItem *mOverlayPolygonItem;
Tile *mTile;
ObjectTemplate *mObjectTemplate;
Copy link
Member

Choose a reason for hiding this comment

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

Why is this a member of CreateObjectTool rather than CreateTemplateTool?

The same question could be asked about mTile of course. That one is there for historical reasons and can be moved to CreateTileObjectTool since change 33e048b.

@thabetx thabetx force-pushed the template-creation branch from a466151 to 01bc2db Compare July 18, 2017 15:42
Copy link
Member

@bjorn bjorn left a comment

Choose a reason for hiding this comment

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

Approved!

I've still noticed a few small changes needed, which you can include in your next PR.

In tidmapper.h, TemplateRef is forward-declared with class, though it is declared as struct. Please make sure the forward-declaration is consistent with the actual declaration, to avoid compiler warnings when compiling with Clang or Visual Studio.

I assume you may have already dealt with the warnings about enumeration values not being handled in some switch statements in propertybrowser.cpp?

src/tiled/propertybrowser.cpp:529: warning: enumeration values 'ObjectTemplateType' and 'TemplateGroupType' not handled in switch [-Wswitch]
    switch (mObject->typeId()) {
            ^

{
Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index);

ObjectTemplate *objectTemplate = toObjectTemplate(index);
Copy link
Member

Choose a reason for hiding this comment

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

Indentation is off by one here.

@bjorn bjorn merged commit d141b87 into mapeditor:wip/templates Jul 25, 2017
@thabetx
Copy link
Contributor Author

thabetx commented Jul 25, 2017

The warnings were not relevant to the pull request so I left them. I will fix them in the next PR.

@thabetx
Copy link
Contributor Author

thabetx commented Jul 25, 2017

I think I will just add them to suppress the warnings without adding any functionality as the new object types are not used in the property browser.

@bjorn
Copy link
Member

bjorn commented Jul 25, 2017

I think I will just add them to suppress the warnings without adding any functionality as the new object types are not used in the property browser.

Sounds reasonable.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants