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

Add object reference property type #1408

Closed
wants to merge 3 commits into from
Closed

Add object reference property type #1408

wants to merge 3 commits into from

Conversation

simlrh
Copy link

@simlrh simlrh commented Dec 8, 2016

Adds an "object" property type; really just another integer but with some UI for easily setting this as the ID of an object in the map.

Similar to the text editor, it's a spinbox for if you already know the ID, or click the button to open a dialog where you can do a text search over all the objects.

Addresses the use case in #707, although only the object ref, not the fancy connecting lines etc!

@simlrh
Copy link
Author

simlrh commented Dec 8, 2016

Hmm. I think there is propbably a simple solution to these build errors, but could someone familiar with Qt point me toward the problem?

@bjorn
Copy link
Member

bjorn commented Dec 8, 2016

Hmm. I think there is probably a simple solution to these build errors, but could someone familiar with Qt point me toward the problem?

The Travis CI build started failing for some other reason, I'm not sure yet what to do about it. The AppVeyor build is failing because you added the new files only to the qmake project, but AppVeyor does the builds using Qbs.

@bjorn
Copy link
Member

bjorn commented Dec 8, 2016

Just having looked quickly over the code, I think this is a really great start! I'll be sure to try it out soon (probably Monday or Tuesday) and do a more detailed review of the code.

src/tiled/objectiddialog.cpp Outdated Show resolved Hide resolved
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.

Overal a nice change and I can see you paid a lot of attention to detail!

I've added some comments, some of which are small tasks but I also asked about a bigger change (using MapObjectModel in the ObjectIdDialog). Just let me know what you'd like to do.

@@ -41,6 +41,10 @@ struct FilePath {
QString absolutePath;
};

struct ObjectId {
int id;
Copy link
Member

Choose a reason for hiding this comment

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

This could use an initializing constructor, setting id to 0.

Utils::restoreGeometry(this);

if (MapDocument *document = DocumentManager::instance()->currentDocument()) {
QTableWidget *tableWidget = mUi->tableWidget;
Copy link
Member

Choose a reason for hiding this comment

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

Rather than using a QTabeWidget and copying all objects into it, did you try using a QTreeView and re-using the MapObjectModel? When combined with a QSortFilterProxyModel, you can still have sorting and filtering work. Also, you could add an ID column to MapObjectModel, but hide it in the ObjectsView (in objectsdock.cpp).

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for this suggestion, this was the first Qt project I've looked at so this was just the first way I figured out to display the items. I'll change this and the QLineEdit.

foreach (QTableWidgetItem *item, items) {
if (item->column() == 0) {
tableWidget->selectRow(item->row());
lineEdit->setText(QStringLiteral(""));
Copy link
Member

Choose a reason for hiding this comment

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

Please use QString() to make an empty string. However, in this case, you should use lineEdit->clear().

connect(mUi->lineEdit, &QLineEdit::textChanged, this, &ObjectIdDialog::onTextChanged);
connect(mUi->tableWidget, &QTableWidget::itemSelectionChanged, this, &ObjectIdDialog::onItemSelectionChanged);
connect(mUi->tableWidget, &QTableWidget::itemDoubleClicked, this, &ObjectIdDialog::onItemDoubleClicked);
connect(mUi->pushButton, &QPushButton::clicked, this, &ObjectIdDialog::onButtonClicked);
Copy link
Member

Choose a reason for hiding this comment

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

Rather than having a separate "Clear" button, please use the functionality built into QLineEdit: http://doc.qt.io/qt-5/qlineedit.html#clearButtonEnabled-prop. I think it's not needed that clicking this button also clears the selection in the list.

reversingproxymodel.cpp
reversingproxymodel.cpp \
objectiddialog.cpp \
objectidedit.cpp
Copy link
Member

Choose a reason for hiding this comment

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

I know it's annoying that it doesn't do it automatically, but please keep these lists sorted. It helps avoid merge conflicts.

if (typeId == objectIdTypeId()) {
ObjectId id = value.value<ObjectId>();

if (MapDocument *document = DocumentManager::instance()->currentDocument()) {
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, this may be a little problematic. There is no guarantee that the current document is the document to which the given ObjectId value is referring. Most of the time it will be true, but for example in the Tile Collision Editor, the objects have their own ID space (though it's a little hacky). I think the only real solution there would be to make the ObjectId contain also a Map*, but actually that won't work for the tile collision editor case since it uses a bare ObjectGroup instance. And if we add an ObjectGroup* to the ObjectId then we'd have to go and keep that up to date, which would be annoying as well.

What are you thoughts on this?

Copy link
Author

Choose a reason for hiding this comment

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

How about a Map* and an int referring to tile id for tile collision objects, or 0 for other objects? Does that uniquely identify all objects to your knowledge?

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, no, you'd need a Tileset* as well. I think adding a Map* and a Tile* would work.

Copy link
Author

Choose a reason for hiding this comment

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

As long as this can be exported into the tmx as tilesets don't have ids. Perhaps in the file it could refer to the tile gid.

Copy link
Member

Choose a reason for hiding this comment

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

In the TMX file there should always just be the ID. The Map* and Tile* are only needed for the VariantPropertyManager to have enough context information to display the name of the object. In the TMX file, this context is clear.

Copy link
Author

Choose a reason for hiding this comment

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

I don't think I follow; I understand the Map* can be omitted, but say there is a property referring to object id 1, and there is an object id 1 in an object layer and another object id 1 in a tile collission object group, how are they differentiated?

Copy link
Member

Choose a reason for hiding this comment

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

They are differentiated by context. An object on a tile collision layer can't ever refer to an object on a tile collision layer from another tile, nor can it refer to an object on a map. So when the Tile* is set instead of the Map*, we need to find the referred object in the ObjectGroup associated with that tile.

if (object->name().length())
label.append(object->name());
else
label.append(QStringLiteral("Unnamed object"));
Copy link
Member

Choose a reason for hiding this comment

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

Please use tr("Unnamed object"), so that it can be translated.

}
}
}
return QStringLiteral("%1: Object not found").arg(QString::number(id.id));
Copy link
Member

Choose a reason for hiding this comment

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

This should be tr("%1: Object not found").arg...

Also, I think a special text would be good for when the id is 0, which can never refer to a valid object. Maybe just "Unset".

Phlosioneer added a commit to Phlosioneer/tiled that referenced this pull request Dec 22, 2019
This commit was based heavily on simlrh's PR of the same name, mapeditor#1408.

Addresses some parts of issue mapeditor#707.
@bjorn
Copy link
Member

bjorn commented Jan 8, 2020

Closing this now that it is superseded by #2712.

@bjorn bjorn closed this Jan 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants