Skip to content

Commit

Permalink
Add object reference property type
Browse files Browse the repository at this point in the history
This commit was based heavily on simlrh's PR of the same name, mapeditor#1408.

Addresses some parts of issue mapeditor#707.
  • Loading branch information
Phlosioneer committed Dec 21, 2019
1 parent 5278c83 commit a905e92
Show file tree
Hide file tree
Showing 14 changed files with 639 additions and 15 deletions.
13 changes: 13 additions & 0 deletions src/libtiled/layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,19 @@ bool Layer::canMergeDown() const
return lowerLayer->canMergeWith(this);
}

QString Layer::parentsAsPath() const
{
const Layer *current = parentLayer();
QString path(name());

while (current) {
path.prepend(current->name() + QLatin1Char('/'));
current = current->parentLayer();
}

return path;
}

/**
* A helper function for initializing the members of the given instance to
* those of this layer. Used by subclasses when cloning.
Expand Down
6 changes: 6 additions & 0 deletions src/libtiled/layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,12 @@ class TILEDSHARED_EXPORT Layer : public Object

bool canMergeDown() const;

/**
* Returns the chain of parent layer names, including this one, in a file-path style
* string.
*/
QString parentsAsPath() const;

virtual bool isEmpty() const = 0;

/**
Expand Down
15 changes: 15 additions & 0 deletions src/libtiled/properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ int filePathTypeId()
return qMetaTypeId<FilePath>();
}

int objectRefTypeId()
{
return qMetaTypeId<ObjectRef>();
}

QString typeToName(int type)
{
switch (type) {
Expand All @@ -121,6 +126,8 @@ QString typeToName(int type)
default:
if (type == filePathTypeId())
return QStringLiteral("file");
if (type == objectRefTypeId())
return QStringLiteral("object");
}
return QLatin1String(QVariant::typeToName(type));
}
Expand All @@ -135,6 +142,8 @@ int nameToType(const QString &name)
return QVariant::Color;
if (name == QLatin1String("file"))
return filePathTypeId();
if (name == QLatin1String("object"))
return objectRefTypeId();

return QVariant::nameToType(name.toLatin1().constData());
}
Expand All @@ -159,6 +168,9 @@ QVariant toExportValue(const QVariant &value)
return filePath.url.toString(QUrl::PreferLocalFile);
}

if (type == objectRefTypeId())
return value.value<ObjectRef>().id;

return value;
}

Expand All @@ -177,6 +189,9 @@ QVariant fromExportValue(const QVariant &value, int type)
return QVariant::fromValue(FilePath { url });
}

if (type == objectRefTypeId())
return QVariant::fromValue(ObjectRef { value.toInt() });

QVariant variant(value);
variant.convert(type);
return variant;
Expand Down
6 changes: 6 additions & 0 deletions src/libtiled/properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ struct FilePath {
QUrl url;
};

struct ObjectRef {
int id;
};

class TILEDSHARED_EXPORT AggregatedPropertyData
{
public:
Expand Down Expand Up @@ -97,6 +101,7 @@ TILEDSHARED_EXPORT QJsonArray propertiesToJson(const Properties &properties);
TILEDSHARED_EXPORT Properties propertiesFromJson(const QJsonArray &json);

TILEDSHARED_EXPORT int filePathTypeId();
TILEDSHARED_EXPORT int objectRefTypeId();

TILEDSHARED_EXPORT QString typeToName(int type);
TILEDSHARED_EXPORT int nameToType(const QString &name);
Expand All @@ -110,3 +115,4 @@ TILEDSHARED_EXPORT QVariant fromExportValue(const QVariant &value, int type, con
} // namespace Tiled

Q_DECLARE_METATYPE(Tiled::FilePath)
Q_DECLARE_METATYPE(Tiled::ObjectRef)
164 changes: 164 additions & 0 deletions src/tiled/objectrefdialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* ObjectRefdialog.cpp
* Copyright 2019, Thorbjørn Lindeijer <[email protected]>
*
* This file is part of Tiled.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "objectrefdialog.h"
#include "ui_objectrefdialog.h"

#include "documentmanager.h"
#include "mapdocument.h"
#include "map.h"
#include "objectgroup.h"
#include "mapobject.h"
#include "utils.h"

#include <QList>
#include <QLineEdit>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QTableWidgetSelectionRange>
#include <QPushButton>
#include <QHeaderView>

namespace Tiled {


ObjectRefDialog::ObjectRefDialog(QWidget *parent)
: QDialog(parent)
, mUi(new Ui::ObjectRefDialog)
, mId(0)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
#endif
mUi->setupUi(this);

Utils::restoreGeometry(this);

// TODO: This assumes we're looking at a map.
if (MapDocument *document = qobject_cast<MapDocument*>(DocumentManager::instance()->currentDocument())) {
QTableWidget *tableWidget = mUi->tableWidget;

QStringList headers = {tr("ID"), tr("Name"), tr("Type"), tr("Parent Layer Path")};
tableWidget->setHorizontalHeaderLabels(headers);
tableWidget->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);

for (const Layer *layer : document->map()->objectGroups()) {
for (const MapObject *object : *static_cast<const ObjectGroup*>(layer))
{
tableWidget->insertRow(tableWidget->rowCount());
int index = tableWidget->rowCount() - 1;
tableWidget->setItem(index, 0, new QTableWidgetItem(QString::number(object->id())));
tableWidget->setItem(index, 1, new QTableWidgetItem(object->name()));
tableWidget->setItem(index, 2, new QTableWidgetItem(object->type()));
tableWidget->setItem(index, 3, new QTableWidgetItem(layer->parentsAsPath()));
}
}
}

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

ObjectRefDialog::~ObjectRefDialog()
{
Utils::saveGeometry(this);
delete mUi;
}

void ObjectRefDialog::setId(const int id)
{
mId = id;

QLineEdit *lineEdit = mUi->lineEdit;
QTableWidget *tableWidget = mUi->tableWidget;
tableWidget->clearSelection();

QList<QTableWidgetItem *> items =
tableWidget->findItems(QString::number(mId), Qt::MatchExactly);

if (items.count() > 0) {
for (const QTableWidgetItem *item : items) {
if (item->column() == 0) {
tableWidget->selectRow(item->row());
lineEdit->setText(QStringLiteral(""));
break;
}
}
}
}

int ObjectRefDialog::id() const
{
return mId;
}

void ObjectRefDialog::onTextChanged(const QString &text)
{
QTableWidget *tableWidget = mUi->tableWidget;
tableWidget->clearSelection();

QList<QTableWidgetItem *> items =
tableWidget->findItems(text, Qt::MatchContains);

bool first = true;
for(int i = 0; i < tableWidget->rowCount(); ++i)
{
bool found = false;
for (const QTableWidgetItem *match : items) {
if (match->row() == i) {
found = true;

if (first) {
tableWidget->selectRow(i);
first = false;
}
}
}
tableWidget->setRowHidden(i, !found);
}
}

void ObjectRefDialog::onItemSelectionChanged()
{
QList<QTableWidgetItem *> items = mUi->tableWidget->selectedItems();
if (items.count()) {
mId = items.at(0)->text().toInt();
} else {
mId = 0;
}
}

void ObjectRefDialog::onItemDoubleClicked(QTableWidgetItem * item)
{
Q_UNUSED(item)
accept();
}

void ObjectRefDialog::onButtonClicked(bool checked)
{
Q_UNUSED(checked)
mUi->lineEdit->clear();
mUi->tableWidget->clearSelection();
}

} // namespace Tiled
56 changes: 56 additions & 0 deletions src/tiled/objectrefdialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* objectrefdialog.h
* Copyright 2019, Thorbjørn Lindeijer <[email protected]>
*
* This file is part of Tiled.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

class ObjectGroup;
class QTableWidgetItem;

#include <QDialog>

namespace Ui {
class ObjectRefDialog;
}

namespace Tiled {

class ObjectRefDialog : public QDialog
{
Q_OBJECT

public:
explicit ObjectRefDialog(QWidget *parent = nullptr);
~ObjectRefDialog();

void setId(const int id);
int id() const;

private:
Ui::ObjectRefDialog *mUi;
int mId;

private slots:
void onTextChanged(const QString &text);
void onItemSelectionChanged();
void onItemDoubleClicked(QTableWidgetItem * item);
void onButtonClicked(bool checked);
};

} // namespace Tiled
Loading

0 comments on commit a905e92

Please sign in to comment.