Fixed sprite rename and refresh bugs
This commit is contained in:
@@ -102,7 +102,14 @@ void BackgroundPropertiesDialog::reject()
|
|||||||
|
|
||||||
void BackgroundPropertiesDialog::loadBackground()
|
void BackgroundPropertiesDialog::loadBackground()
|
||||||
{
|
{
|
||||||
const auto path = QFileDialog::getOpenFileName(this, tr("Open a Background Image..."), {}, tr("BMP Files (*.bmp), PNG Files (*png)"));
|
const auto path = QFileDialog::getOpenFileName(this, tr("Open a Background Image..."), {},
|
||||||
|
QStringLiteral("%0 (*.png);;%1 (*.bmp);;%2 (*.tiff);;%3 (*.jpg *.jpeg);;%4 (*)")
|
||||||
|
.arg(tr("PNG Files"))
|
||||||
|
.arg(tr("BMP Files"))
|
||||||
|
.arg(tr("TIFF Files"))
|
||||||
|
.arg(tr("JPEG Files"))
|
||||||
|
.arg(tr("All Files"))
|
||||||
|
);
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -126,7 +133,14 @@ void BackgroundPropertiesDialog::saveBackground()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto path = QFileDialog::getSaveFileName(this, tr("Save a Background Image..."), m_background.name + ".png", tr("PNG Files (*.png)"));
|
const auto path = QFileDialog::getSaveFileName(this, tr("Save a Background Image..."), m_background.name + ".png",
|
||||||
|
QStringLiteral("%0 (*.png);;%1 (*.bmp);;%2 (*.tiff);;%3 (*.jpg *.jpeg);;%4 (*)")
|
||||||
|
.arg(tr("PNG Files"))
|
||||||
|
.arg(tr("BMP Files"))
|
||||||
|
.arg(tr("TIFF Files"))
|
||||||
|
.arg(tr("JPEG Files"))
|
||||||
|
.arg(tr("All Files"))
|
||||||
|
);
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -32,16 +32,7 @@ ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel
|
|||||||
|
|
||||||
m_ui->lineEditName->setText(m_object.name);
|
m_ui->lineEditName->setText(m_object.name);
|
||||||
m_ui->lineEditSprite->setText(m_spriteName.isEmpty() ? tr("<no sprite>") : m_spriteName);
|
m_ui->lineEditSprite->setText(m_spriteName.isEmpty() ? tr("<no sprite>") : m_spriteName);
|
||||||
if (!m_spriteName.isEmpty())
|
updateSpritePreview();
|
||||||
{
|
|
||||||
const auto &sprites = m_projectModel.project()->sprites;
|
|
||||||
const auto iter = std::find_if(std::cbegin(sprites), std::cend(sprites),
|
|
||||||
[&](const Sprite &sprite){ return sprite.name == m_spriteName; });
|
|
||||||
if (iter == std::cend(sprites))
|
|
||||||
qWarning() << "sprite" << m_spriteName << "not found";
|
|
||||||
else
|
|
||||||
m_ui->labelSpritePreview->setPixmap(iter->pixmaps.empty() ? QPixmap{} : iter->pixmaps.front().scaled(m_ui->labelSpritePreview->size(), Qt::KeepAspectRatio));
|
|
||||||
}
|
|
||||||
m_ui->toolButtonSprite->setMenu(m_spritesMenu);
|
m_ui->toolButtonSprite->setMenu(m_spritesMenu);
|
||||||
m_ui->checkBoxVisible->setChecked(m_object.visible);
|
m_ui->checkBoxVisible->setChecked(m_object.visible);
|
||||||
m_ui->checkBoxSolid->setChecked(m_object.solid);
|
m_ui->checkBoxSolid->setChecked(m_object.solid);
|
||||||
@@ -52,6 +43,12 @@ ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel
|
|||||||
|
|
||||||
connect(&m_projectModel, &ProjectTreeModel::objectNameChanged,
|
connect(&m_projectModel, &ProjectTreeModel::objectNameChanged,
|
||||||
this, &ObjectPropertiesDialog::objectNameChanged);
|
this, &ObjectPropertiesDialog::objectNameChanged);
|
||||||
|
connect(&m_projectModel, &ProjectTreeModel::spriteNameChanged,
|
||||||
|
this, &ObjectPropertiesDialog::spriteNameChanged);
|
||||||
|
connect(&m_projectModel, &ProjectTreeModel::spriteAboutToBeRemoved,
|
||||||
|
this, &ObjectPropertiesDialog::spriteAboutToBeRemoved);
|
||||||
|
connect(&m_projectModel, &ProjectTreeModel::spritePixmapsChanged,
|
||||||
|
this, &ObjectPropertiesDialog::spritePixmapsChanged);
|
||||||
|
|
||||||
connect(m_eventsModel.get(), &QAbstractItemModel::modelReset,
|
connect(m_eventsModel.get(), &QAbstractItemModel::modelReset,
|
||||||
this, &ObjectPropertiesDialog::changed);
|
this, &ObjectPropertiesDialog::changed);
|
||||||
@@ -241,6 +238,49 @@ void ObjectPropertiesDialog::objectNameChanged(const Object &object)
|
|||||||
updateTitle();
|
updateTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesDialog::spriteNameChanged(const Sprite &sprite, const QString &oldName)
|
||||||
|
{
|
||||||
|
if (m_spriteName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_spriteName != oldName)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_spriteName = sprite.name;
|
||||||
|
{
|
||||||
|
QSignalBlocker blocker{m_ui->lineEditSprite};
|
||||||
|
m_ui->lineEditSprite->setText(sprite.name);
|
||||||
|
}
|
||||||
|
updateSpritePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesDialog::spriteAboutToBeRemoved(const Sprite &sprite)
|
||||||
|
{
|
||||||
|
if (m_spriteName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_spriteName != sprite.name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_spriteName.clear();
|
||||||
|
{
|
||||||
|
QSignalBlocker blocker{m_ui->lineEditSprite};
|
||||||
|
m_ui->lineEditSprite->setText(tr("<no sprite>"));
|
||||||
|
}
|
||||||
|
m_ui->labelSpritePreview->setPixmap(QPixmap{});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesDialog::spritePixmapsChanged(const Sprite &sprite)
|
||||||
|
{
|
||||||
|
if (m_spriteName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_spriteName != sprite.name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
updateSpritePreview(sprite.pixmaps);
|
||||||
|
}
|
||||||
|
|
||||||
void ObjectPropertiesDialog::spritesMenuAboutToShow()
|
void ObjectPropertiesDialog::spritesMenuAboutToShow()
|
||||||
{
|
{
|
||||||
m_spritesMenu->clear();
|
m_spritesMenu->clear();
|
||||||
@@ -283,17 +323,17 @@ void ObjectPropertiesDialog::eventsContextMenuRequested(const QPoint &pos)
|
|||||||
|
|
||||||
void ObjectPropertiesDialog::clearSprite()
|
void ObjectPropertiesDialog::clearSprite()
|
||||||
{
|
{
|
||||||
|
m_spriteName.clear();
|
||||||
m_ui->labelSpritePreview->setPixmap(QPixmap{});
|
m_ui->labelSpritePreview->setPixmap(QPixmap{});
|
||||||
m_ui->lineEditSprite->setText(tr("<no sprite>"));
|
m_ui->lineEditSprite->setText(tr("<no sprite>"));
|
||||||
m_spriteName = QString{};
|
|
||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectPropertiesDialog::setSprite(const Sprite &sprite)
|
void ObjectPropertiesDialog::setSprite(const Sprite &sprite)
|
||||||
{
|
{
|
||||||
m_ui->labelSpritePreview->setPixmap(sprite.pixmaps.empty() ? QPixmap{} : sprite.pixmaps.front().scaled(m_ui->labelSpritePreview->size(), Qt::KeepAspectRatio));
|
|
||||||
m_ui->lineEditSprite->setText(sprite.name);
|
|
||||||
m_spriteName = sprite.name;
|
m_spriteName = sprite.name;
|
||||||
|
updateSpritePreview(sprite.pixmaps);
|
||||||
|
m_ui->lineEditSprite->setText(sprite.name);
|
||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,3 +344,24 @@ void ObjectPropertiesDialog::updateTitle()
|
|||||||
.arg(m_unsavedChanges ? tr("*") : QString{})
|
.arg(m_unsavedChanges ? tr("*") : QString{})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesDialog::updateSpritePreview()
|
||||||
|
{
|
||||||
|
if (m_spriteName.isEmpty())
|
||||||
|
m_ui->labelSpritePreview->setPixmap(QPixmap{});
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto &sprites = m_projectModel.project()->sprites;
|
||||||
|
const auto iter = std::find_if(std::cbegin(sprites), std::cend(sprites),
|
||||||
|
[&](const Sprite &sprite){ return sprite.name == m_spriteName; });
|
||||||
|
if (iter == std::cend(sprites))
|
||||||
|
qWarning() << "sprite" << m_spriteName << "not found";
|
||||||
|
else
|
||||||
|
updateSpritePreview(iter->pixmaps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesDialog::updateSpritePreview(const std::vector<QPixmap> &pixmaps)
|
||||||
|
{
|
||||||
|
m_ui->labelSpritePreview->setPixmap(pixmaps.empty() ? QPixmap{} : pixmaps.front().scaled(32, m_ui->labelSpritePreview->height(), Qt::KeepAspectRatio));
|
||||||
|
}
|
||||||
|
@@ -35,6 +35,9 @@ private slots:
|
|||||||
void changed();
|
void changed();
|
||||||
|
|
||||||
void objectNameChanged(const Object &object);
|
void objectNameChanged(const Object &object);
|
||||||
|
void spriteNameChanged(const Sprite &sprite, const QString &oldName);
|
||||||
|
void spriteAboutToBeRemoved(const Sprite &sprite);
|
||||||
|
void spritePixmapsChanged(const Sprite &sprite);
|
||||||
|
|
||||||
void spritesMenuAboutToShow();
|
void spritesMenuAboutToShow();
|
||||||
void currentEventChanged(const QModelIndex &index);
|
void currentEventChanged(const QModelIndex &index);
|
||||||
@@ -45,6 +48,8 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void updateTitle();
|
void updateTitle();
|
||||||
|
void updateSpritePreview();
|
||||||
|
void updateSpritePreview(const std::vector<QPixmap> &pixmaps);
|
||||||
|
|
||||||
const std::unique_ptr<Ui::ObjectPropertiesDialog> m_ui;
|
const std::unique_ptr<Ui::ObjectPropertiesDialog> m_ui;
|
||||||
|
|
||||||
|
@@ -79,7 +79,12 @@ void SpritePropertiesDialog::accept()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sprite.pixmaps = std::move(m_pixmaps);
|
if (!m_projectModel.setSpritePixmaps(m_sprite, std::move(m_pixmaps)))
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Setting Sprite pixmaps failed!"), tr("Setting Sprite pixmaps failed!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_sprite.origin.x = m_ui->spinBoxOriginX->value();
|
m_sprite.origin.x = m_ui->spinBoxOriginX->value();
|
||||||
m_sprite.origin.y = m_ui->spinBoxOriginY->value();
|
m_sprite.origin.y = m_ui->spinBoxOriginY->value();
|
||||||
m_sprite.preciseCollisionChecking = m_ui->checkBoxPreciseCollisionChecking->isChecked();
|
m_sprite.preciseCollisionChecking = m_ui->checkBoxPreciseCollisionChecking->isChecked();
|
||||||
@@ -120,7 +125,14 @@ void SpritePropertiesDialog::reject()
|
|||||||
|
|
||||||
void SpritePropertiesDialog::loadSprite()
|
void SpritePropertiesDialog::loadSprite()
|
||||||
{
|
{
|
||||||
const auto path = QFileDialog::getOpenFileName(this, tr("Open a Sprite Image..."), {}, tr("BMP Files (*.bmp), PNG Files (*png)"));
|
const auto path = QFileDialog::getOpenFileName(this, tr("Open a Sprite Image..."), {},
|
||||||
|
QStringLiteral("%0 (*.png);;%1 (*.bmp);;%2 (*.tiff);;%3 (*.jpg *.jpeg);;%4 (*)")
|
||||||
|
.arg(tr("PNG Files"))
|
||||||
|
.arg(tr("BMP Files"))
|
||||||
|
.arg(tr("TIFF Files"))
|
||||||
|
.arg(tr("JPEG Files"))
|
||||||
|
.arg(tr("All Files"))
|
||||||
|
);
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -144,7 +156,14 @@ void SpritePropertiesDialog::saveSprite()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto path = QFileDialog::getSaveFileName(this, tr("Save a Sprite Image..."), m_sprite.name + ".png", tr("PNG Files (*.png)"));
|
const auto path = QFileDialog::getSaveFileName(this, tr("Save a Sprite Image..."), m_sprite.name + ".png",
|
||||||
|
QStringLiteral("%0 (*.png);;%1 (*.bmp);;%2 (*.tiff);;%3 (*.jpg *.jpeg);;%4 (*)")
|
||||||
|
.arg(tr("PNG Files"))
|
||||||
|
.arg(tr("BMP Files"))
|
||||||
|
.arg(tr("TIFF Files"))
|
||||||
|
.arg(tr("JPEG Files"))
|
||||||
|
.arg(tr("All Files"))
|
||||||
|
);
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
#include <QIcon>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -228,10 +229,10 @@ QVariant ProjectTreeModel::data(const QModelIndex &index, int role) const
|
|||||||
case RowFonts:
|
case RowFonts:
|
||||||
case RowTimeLines:
|
case RowTimeLines:
|
||||||
case RowObjects:
|
case RowObjects:
|
||||||
case RowRooms: return QPixmap{":/qtgameengine/icons/folder.png"}.scaled(16, 16);
|
case RowRooms: return QIcon{":/qtgameengine/icons/folder.png"};
|
||||||
case RowGameInformation: return QPixmap{":/qtgameengine/icons/game-information-file.png"}.scaled(16, 16);
|
case RowGameInformation: return QIcon{":/qtgameengine/icons/game-information-file.png"};
|
||||||
case RowGlobalGameSettings: return QPixmap{":/qtgameengine/icons/global-game-settings-file.png"}.scaled(16, 16);
|
case RowGlobalGameSettings: return QIcon{":/qtgameengine/icons/global-game-settings-file.png"};
|
||||||
case RowExtensionPackages: return QPixmap{":/qtgameengine/icons/extension-packages-file.png"}.scaled(16, 16);
|
case RowExtensionPackages: return QIcon{":/qtgameengine/icons/extension-packages-file.png"};
|
||||||
default:
|
default:
|
||||||
qWarning() << "unexpected root row" << index.row();
|
qWarning() << "unexpected root row" << index.row();
|
||||||
return {};
|
return {};
|
||||||
@@ -493,9 +494,56 @@ template const Object *ProjectTreeModel::get<Object>(const QModelIndex &index) c
|
|||||||
template Room *ProjectTreeModel::get<Room>(const QModelIndex &index);
|
template Room *ProjectTreeModel::get<Room>(const QModelIndex &index);
|
||||||
template const Room *ProjectTreeModel::get<Room>(const QModelIndex &index) const;
|
template const Room *ProjectTreeModel::get<Room>(const QModelIndex &index) const;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool ProjectTreeModel::remove(const T &entry)
|
||||||
|
{
|
||||||
|
if (!m_project)
|
||||||
|
{
|
||||||
|
qWarning() << "unexpected null project";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &container = m_project->containerFor<T>();
|
||||||
|
const auto iter = std::find_if(std::begin(container), std::end(container),
|
||||||
|
[&entry](const auto &otherEntry){ return &entry == &otherEntry; });
|
||||||
|
if (iter == std::cend(container))
|
||||||
|
{
|
||||||
|
qWarning() << "entry not from this project!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto row = std::distance(std::begin(container), iter);
|
||||||
|
|
||||||
|
onBeforeRemove<T>(*iter);
|
||||||
|
|
||||||
|
emitAboutToBeRemoved<T>(*iter);
|
||||||
|
|
||||||
|
beginRemoveRows(rootFor<T>(), row, row);
|
||||||
|
container.erase(iter);
|
||||||
|
endRemoveRows();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template bool ProjectTreeModel::remove<Sprite>(const Sprite &entry);
|
||||||
|
template bool ProjectTreeModel::remove<Sound>(const Sound &entry);
|
||||||
|
template bool ProjectTreeModel::remove<Background>(const Background &entry);
|
||||||
|
template bool ProjectTreeModel::remove<Path>(const Path &entry);
|
||||||
|
template bool ProjectTreeModel::remove<Script>(const Script &entry);
|
||||||
|
template bool ProjectTreeModel::remove<Font>(const Font &entry);
|
||||||
|
template bool ProjectTreeModel::remove<TimeLine>(const TimeLine &entry);
|
||||||
|
template bool ProjectTreeModel::remove<Object>(const Object &entry);
|
||||||
|
template bool ProjectTreeModel::remove<Room>(const Room &entry);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool ProjectTreeModel::rename(const T &entry, const QString &newName)
|
bool ProjectTreeModel::rename(const T &entry, const QString &newName)
|
||||||
{
|
{
|
||||||
|
if (!m_project)
|
||||||
|
{
|
||||||
|
qWarning() << "unexpected null project";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto &container = m_project->containerFor<T>();
|
auto &container = m_project->containerFor<T>();
|
||||||
const auto iter = std::find_if(std::begin(container), std::end(container),
|
const auto iter = std::find_if(std::begin(container), std::end(container),
|
||||||
[&entry](const auto &otherEntry){ return &entry == &otherEntry; });
|
[&entry](const auto &otherEntry){ return &entry == &otherEntry; });
|
||||||
@@ -515,12 +563,17 @@ bool ProjectTreeModel::rename(const T &entry, const QString &newName)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
iter->name = newName;
|
onBeforeRename<T>(*iter, newName);
|
||||||
|
|
||||||
emitNameChanged<T>(*iter);
|
auto oldName = std::move(iter->name);
|
||||||
|
iter->name = std::move(newName);
|
||||||
|
|
||||||
|
emitNameChanged<T>(*iter, oldName);
|
||||||
const auto index = this->index(std::distance(std::begin(container), iter), 0, rootFor<T>());
|
const auto index = this->index(std::distance(std::begin(container), iter), 0, rootFor<T>());
|
||||||
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
|
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
|
||||||
|
|
||||||
|
onAfterRename<T>(*iter, std::move(oldName));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,6 +587,44 @@ template bool ProjectTreeModel::rename<TimeLine>(const TimeLine &entry, const QS
|
|||||||
template bool ProjectTreeModel::rename<Object>(const Object &entry, const QString &newName);
|
template bool ProjectTreeModel::rename<Object>(const Object &entry, const QString &newName);
|
||||||
template bool ProjectTreeModel::rename<Room>(const Room &entry, const QString &newName);
|
template bool ProjectTreeModel::rename<Room>(const Room &entry, const QString &newName);
|
||||||
|
|
||||||
|
bool ProjectTreeModel::setSpritePixmaps(const Sprite &sprite, std::vector<QPixmap> &&pixmaps)
|
||||||
|
{
|
||||||
|
if (!m_project)
|
||||||
|
{
|
||||||
|
qWarning() << "unexpected null project";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto &container = m_project->sprites;
|
||||||
|
const auto iter = std::find_if(std::begin(container), std::end(container),
|
||||||
|
[&sprite](const auto &otherEntry){ return &sprite == &otherEntry; });
|
||||||
|
if (iter == std::cend(container))
|
||||||
|
{
|
||||||
|
qWarning() << "entry not from this project!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter->pixmaps = std::move(pixmaps);
|
||||||
|
|
||||||
|
const auto index = this->index(std::distance(std::begin(container), iter), 0, rootFor<Sprite>());
|
||||||
|
emit dataChanged(index, index, { Qt::DecorationRole });
|
||||||
|
|
||||||
|
emit spritePixmapsChanged(*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto iter = std::cbegin(m_project->objects); iter != std::cend(m_project->objects); iter++)
|
||||||
|
{
|
||||||
|
if (iter->spriteName != sprite.name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto index = this->index(std::distance(std::cbegin(m_project->objects), iter), 0, rootFor<Object>());
|
||||||
|
emit dataChanged(index, index, {Qt::DecorationRole});
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
QVariant ProjectTreeModel::dataFor(const QModelIndex &index, int role) const
|
QVariant ProjectTreeModel::dataFor(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
@@ -574,7 +665,7 @@ QVariant ProjectTreeModel::iconFor<Sprite>(const Sprite &entry) const
|
|||||||
pixmap.fill(Qt::white);
|
pixmap.fill(Qt::white);
|
||||||
return pixmap;
|
return pixmap;
|
||||||
}
|
}
|
||||||
return entry.pixmaps.front().scaled(16, 16, Qt::IgnoreAspectRatio /*KeepAspectRatio*/);
|
return QIcon{entry.pixmaps.front()};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@@ -583,9 +674,9 @@ QVariant ProjectTreeModel::iconFor<Sound>(const Sound &entry) const
|
|||||||
switch (entry.type)
|
switch (entry.type)
|
||||||
{
|
{
|
||||||
case Sound::Type::Sound:
|
case Sound::Type::Sound:
|
||||||
return QPixmap{":/qtgameengine/icons/sound-file.png"}.scaled(16, 16);
|
return QIcon{":/qtgameengine/icons/sound-file.png"};
|
||||||
case Sound::Type::Music:
|
case Sound::Type::Music:
|
||||||
return QPixmap{":/qtgameengine/icons/music-file.png"}.scaled(16, 16);
|
return QIcon{":/qtgameengine/icons/music-file.png"};
|
||||||
default:
|
default:
|
||||||
qWarning() << "unexpected sound type" << std::to_underlying(entry.type);
|
qWarning() << "unexpected sound type" << std::to_underlying(entry.type);
|
||||||
return {};
|
return {};
|
||||||
@@ -597,39 +688,39 @@ QVariant ProjectTreeModel::iconFor<Background>(const Background &entry) const
|
|||||||
{
|
{
|
||||||
if (entry.pixmap.isNull())
|
if (entry.pixmap.isNull())
|
||||||
{
|
{
|
||||||
QPixmap pixmap{16, 16};
|
QPixmap pixmap{64, 64};
|
||||||
pixmap.fill(Qt::white);
|
pixmap.fill(Qt::white);
|
||||||
return pixmap;
|
return QIcon{pixmap};
|
||||||
}
|
}
|
||||||
return entry.pixmap.scaled(16, 16, Qt::KeepAspectRatio);
|
return QIcon{entry.pixmap};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
QVariant ProjectTreeModel::iconFor<Path>(const Path &entry) const
|
QVariant ProjectTreeModel::iconFor<Path>(const Path &entry) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(entry)
|
Q_UNUSED(entry)
|
||||||
return QPixmap{":/qtgameengine/icons/path-file.png"}.scaled(16, 16);
|
return QIcon{":/qtgameengine/icons/path-file.png"};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
QVariant ProjectTreeModel::iconFor<Script>(const Script &entry) const
|
QVariant ProjectTreeModel::iconFor<Script>(const Script &entry) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(entry)
|
Q_UNUSED(entry)
|
||||||
return QPixmap{":/qtgameengine/icons/script-file.png"}.scaled(16, 16);
|
return QIcon{":/qtgameengine/icons/script-file.png"};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
QVariant ProjectTreeModel::iconFor<Font>(const Font &entry) const
|
QVariant ProjectTreeModel::iconFor<Font>(const Font &entry) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(entry)
|
Q_UNUSED(entry)
|
||||||
return QPixmap{":/qtgameengine/icons/font-file.png"}.scaled(16, 16);
|
return QIcon{":/qtgameengine/icons/font-file.png"};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
QVariant ProjectTreeModel::iconFor<TimeLine>(const TimeLine &entry) const
|
QVariant ProjectTreeModel::iconFor<TimeLine>(const TimeLine &entry) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(entry)
|
Q_UNUSED(entry)
|
||||||
return QPixmap{":/qtgameengine/icons/timeline-file.png"}.scaled(16, 16);
|
return QIcon{":/qtgameengine/icons/timeline-file.png"};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
@@ -642,19 +733,19 @@ QVariant ProjectTreeModel::iconFor<Object>(const Object &entry) const
|
|||||||
if (iter == std::cend(m_project->sprites))
|
if (iter == std::cend(m_project->sprites))
|
||||||
qWarning() << "sprite" << entry.spriteName << "not found";
|
qWarning() << "sprite" << entry.spriteName << "not found";
|
||||||
else if (!iter->pixmaps.empty() && !iter->pixmaps.front().isNull())
|
else if (!iter->pixmaps.empty() && !iter->pixmaps.front().isNull())
|
||||||
return iter->pixmaps.front().scaled(16, 16, Qt::KeepAspectRatio);
|
return QIcon{iter->pixmaps.front()};
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap pixmap{16, 16};
|
QPixmap pixmap{64, 64};
|
||||||
pixmap.fill(Qt::white);
|
pixmap.fill(Qt::white);
|
||||||
return pixmap;
|
return QIcon{pixmap};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
QVariant ProjectTreeModel::iconFor<Room>(const Room &entry) const
|
QVariant ProjectTreeModel::iconFor<Room>(const Room &entry) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(entry)
|
Q_UNUSED(entry)
|
||||||
return QPixmap{":/qtgameengine/icons/room-file.png"}.scaled(16, 16);
|
return QIcon{":/qtgameengine/icons/room-file.png"};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -686,9 +777,12 @@ bool ProjectTreeModel::setDataFor(const QModelIndex &index, const QVariant &valu
|
|||||||
emit errorOccured(tr("A Sprite with the name \"%0\" is already existing").arg(name));
|
emit errorOccured(tr("A Sprite with the name \"%0\" is already existing").arg(name));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
onBeforeRename<T>(*iter, name);
|
||||||
|
auto oldName = std::move(iter->name);
|
||||||
iter->name = std::move(name);
|
iter->name = std::move(name);
|
||||||
emitNameChanged<T>(*iter);
|
emitNameChanged<T>(*iter, oldName);
|
||||||
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
|
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
|
||||||
|
onAfterRename<T>(*iter, std::move(oldName));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
@@ -759,9 +853,16 @@ std::optional<bool> ProjectTreeModel::removeRowsFor(int row, int count, const QM
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit beginRemoveRows(parent, row, row + count - 1);
|
|
||||||
auto begin = std::next(std::begin(container), row);
|
auto begin = std::next(std::begin(container), row);
|
||||||
auto end = std::next(begin, count);
|
auto end = std::next(begin, count);
|
||||||
|
|
||||||
|
for (auto iter = begin; iter != end; iter++)
|
||||||
|
onBeforeRemove<T>(*iter);
|
||||||
|
|
||||||
|
for (auto iter = begin; iter != end; iter++)
|
||||||
|
emitAboutToBeRemoved(*iter);
|
||||||
|
|
||||||
|
emit beginRemoveRows(parent, row, row + count - 1);
|
||||||
container.erase(begin, end);
|
container.erase(begin, end);
|
||||||
emit endRemoveRows();
|
emit endRemoveRows();
|
||||||
|
|
||||||
@@ -771,110 +872,69 @@ std::optional<bool> ProjectTreeModel::removeRowsFor(int row, int count, const QM
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<typename T> void ProjectTreeModel::onBeforeRemove(const T &entry) {}
|
||||||
void ProjectTreeModel::emitNameChanged<Sprite>(const Sprite &entry)
|
template<> void ProjectTreeModel::onBeforeRemove<Sprite>(const Sprite &sprite)
|
||||||
{
|
{
|
||||||
emit spriteNameChanged(entry);
|
for (auto iter = std::begin(m_project->objects); iter != std::end(m_project->objects); iter++)
|
||||||
|
{
|
||||||
|
if (iter->spriteName != sprite.name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto oldSpriteName = std::move(iter->spriteName);
|
||||||
|
iter->spriteName.clear();
|
||||||
|
|
||||||
|
const auto index = this->index(std::distance(std::begin(m_project->objects), iter), 0, rootFor<Object>());
|
||||||
|
emit dataChanged(index, index, {Qt::DecorationRole});
|
||||||
|
|
||||||
|
emit objectSpriteNameChanged(*iter, std::move(oldSpriteName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<typename T> void ProjectTreeModel::onBeforeRename(const T &entry, const QString &newName) {}
|
||||||
void ProjectTreeModel::emitNameChanged<Sound>(const Sound &entry)
|
|
||||||
|
template<typename T> void ProjectTreeModel::onAfterRename(const T &entry, const QString &oldName) {}
|
||||||
|
template<> void ProjectTreeModel::onAfterRename<Sprite>(const Sprite &sprite, const QString &oldName)
|
||||||
{
|
{
|
||||||
emit soundNameChanged(entry);
|
for (auto iter = std::begin(m_project->objects); iter != std::end(m_project->objects); iter++)
|
||||||
|
{
|
||||||
|
if (iter->spriteName != oldName)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto oldSpriteName = std::move(iter->spriteName);
|
||||||
|
|
||||||
|
iter->spriteName = sprite.name;
|
||||||
|
|
||||||
|
// const auto index = this->index(std::distance(std::begin(m_project->objects), iter), 0, rootFor<Object>());
|
||||||
|
// emit dataChanged(index, index, {Qt::DecorationRole});
|
||||||
|
|
||||||
|
emit objectSpriteNameChanged(*iter, std::move(oldSpriteName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<> void ProjectTreeModel::emitAboutToBeRemoved<Sprite>(const Sprite &entry) { emit spriteAboutToBeRemoved(entry); }
|
||||||
void ProjectTreeModel::emitNameChanged<Background>(const Background &entry)
|
template<> void ProjectTreeModel::emitAboutToBeRemoved<Sound>(const Sound &entry) { emit soundAboutToBeRemoved(entry); }
|
||||||
{
|
template<> void ProjectTreeModel::emitAboutToBeRemoved<Background>(const Background &entry) { emit backgroundAboutToBeRemoved(entry); }
|
||||||
emit backgroundNameChanged(entry);
|
template<> void ProjectTreeModel::emitAboutToBeRemoved<Path>(const Path &entry) { emit pathAboutToBeRemoved(entry); }
|
||||||
}
|
template<> void ProjectTreeModel::emitAboutToBeRemoved<Script>(const Script &entry) { emit scriptAboutToBeRemoved(entry); }
|
||||||
|
template<> void ProjectTreeModel::emitAboutToBeRemoved<Font>(const Font &entry) { emit fontAboutToBeRemoved(entry); }
|
||||||
template<>
|
template<> void ProjectTreeModel::emitAboutToBeRemoved<TimeLine>(const TimeLine &entry) { emit timeLineAboutToBeRemoved(entry); }
|
||||||
void ProjectTreeModel::emitNameChanged<Path>(const Path &entry)
|
template<> void ProjectTreeModel::emitAboutToBeRemoved<Object>(const Object &entry) { emit objectAboutToBeRemoved(entry); }
|
||||||
{
|
template<> void ProjectTreeModel::emitAboutToBeRemoved<Room>(const Room &entry) { emit roomAboutToBeRemoved(entry); }
|
||||||
emit pathNameChanged(entry);
|
template<> void ProjectTreeModel::emitNameChanged<Sprite>(const Sprite &entry, const QString &oldName) { emit spriteNameChanged(entry, oldName); }
|
||||||
}
|
template<> void ProjectTreeModel::emitNameChanged<Sound>(const Sound &entry, const QString &oldName) { emit soundNameChanged(entry, oldName); }
|
||||||
|
template<> void ProjectTreeModel::emitNameChanged<Background>(const Background &entry, const QString &oldName) { emit backgroundNameChanged(entry, oldName); }
|
||||||
template<>
|
template<> void ProjectTreeModel::emitNameChanged<Path>(const Path &entry, const QString &oldName) { emit pathNameChanged(entry, oldName); }
|
||||||
void ProjectTreeModel::emitNameChanged<Script>(const Script &entry)
|
template<> void ProjectTreeModel::emitNameChanged<Script>(const Script &entry, const QString &oldName) { emit scriptNameChanged(entry, oldName); }
|
||||||
{
|
template<> void ProjectTreeModel::emitNameChanged<Font>(const Font &entry, const QString &oldName) { emit fontNameChanged(entry, oldName); }
|
||||||
emit scriptNameChanged(entry);
|
template<> void ProjectTreeModel::emitNameChanged<TimeLine>(const TimeLine &entry, const QString &oldName) { emit timeLineNameChanged(entry, oldName); }
|
||||||
}
|
template<> void ProjectTreeModel::emitNameChanged<Object>(const Object &entry, const QString &oldName) { emit objectNameChanged(entry, oldName); }
|
||||||
|
template<> void ProjectTreeModel::emitNameChanged<Room>(const Room &entry, const QString &oldName) { emit roomNameChanged(entry, oldName); }
|
||||||
template<>
|
template<> QString ProjectTreeModel::nameTempateFor<Sprite>() { return QStringLiteral("sprite%0"); }
|
||||||
void ProjectTreeModel::emitNameChanged<Font>(const Font &entry)
|
template<> QString ProjectTreeModel::nameTempateFor<Sound>() { return QStringLiteral("sound%0"); }
|
||||||
{
|
template<> QString ProjectTreeModel::nameTempateFor<Background>() { return QStringLiteral("background%0"); }
|
||||||
emit fontNameChanged(entry);
|
template<> QString ProjectTreeModel::nameTempateFor<Path>() { return QStringLiteral("path%0"); }
|
||||||
}
|
template<> QString ProjectTreeModel::nameTempateFor<Script>() { return QStringLiteral("script%0"); }
|
||||||
|
template<> QString ProjectTreeModel::nameTempateFor<Font>() { return QStringLiteral("font%0"); }
|
||||||
template<>
|
template<> QString ProjectTreeModel::nameTempateFor<TimeLine>() { return QStringLiteral("timeline%0"); }
|
||||||
void ProjectTreeModel::emitNameChanged<TimeLine>(const TimeLine &entry)
|
template<> QString ProjectTreeModel::nameTempateFor<Object>() { return QStringLiteral("object%0"); }
|
||||||
{
|
template<> QString ProjectTreeModel::nameTempateFor<Room>() { return QStringLiteral("room%0"); }
|
||||||
emit timeLineNameChanged(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
void ProjectTreeModel::emitNameChanged<Object>(const Object &entry)
|
|
||||||
{
|
|
||||||
emit objectNameChanged(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
void ProjectTreeModel::emitNameChanged<Room>(const Room &entry)
|
|
||||||
{
|
|
||||||
emit roomNameChanged(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
QString ProjectTreeModel::nameTempateFor<Sprite>()
|
|
||||||
{
|
|
||||||
return QStringLiteral("sprite%0");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
QString ProjectTreeModel::nameTempateFor<Sound>()
|
|
||||||
{
|
|
||||||
return QStringLiteral("sound%0");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
QString ProjectTreeModel::nameTempateFor<Background>()
|
|
||||||
{
|
|
||||||
return QStringLiteral("background%0");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
QString ProjectTreeModel::nameTempateFor<Path>()
|
|
||||||
{
|
|
||||||
return QStringLiteral("path%0");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
QString ProjectTreeModel::nameTempateFor<Script>()
|
|
||||||
{
|
|
||||||
return QStringLiteral("script%0");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
QString ProjectTreeModel::nameTempateFor<Font>()
|
|
||||||
{
|
|
||||||
return QStringLiteral("font%0");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
QString ProjectTreeModel::nameTempateFor<TimeLine>()
|
|
||||||
{
|
|
||||||
return QStringLiteral("timeline%0");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
QString ProjectTreeModel::nameTempateFor<Object>()
|
|
||||||
{
|
|
||||||
return QStringLiteral("object%0");
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
QString ProjectTreeModel::nameTempateFor<Room>()
|
|
||||||
{
|
|
||||||
return QStringLiteral("room%0");
|
|
||||||
}
|
|
||||||
|
@@ -64,10 +64,14 @@ public:
|
|||||||
template<typename T> T *get(const QModelIndex &index);
|
template<typename T> T *get(const QModelIndex &index);
|
||||||
template<typename T> const T *get(const QModelIndex &index) const;
|
template<typename T> const T *get(const QModelIndex &index) const;
|
||||||
|
|
||||||
template<typename T> bool rename(const T &sprite, const QString &newName);
|
template<typename T> bool remove(const T &entry);
|
||||||
|
|
||||||
|
template<typename T> bool rename(const T &entry, const QString &newName);
|
||||||
|
|
||||||
template<typename T> static constexpr ProjectTreeModel::NodeType nodeTypeFor() = delete;
|
template<typename T> static constexpr ProjectTreeModel::NodeType nodeTypeFor() = delete;
|
||||||
|
|
||||||
|
bool setSpritePixmaps(const Sprite &sprite, std::vector<QPixmap> &&pixmaps);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void errorOccured(const QString &message);
|
void errorOccured(const QString &message);
|
||||||
|
|
||||||
@@ -81,15 +85,19 @@ signals:
|
|||||||
void objectAboutToBeRemoved(const Object &font);
|
void objectAboutToBeRemoved(const Object &font);
|
||||||
void roomAboutToBeRemoved(const Room &font);
|
void roomAboutToBeRemoved(const Room &font);
|
||||||
|
|
||||||
void spriteNameChanged(const Sprite &sprite);
|
void spriteNameChanged(const Sprite &sprite, const QString &oldName);
|
||||||
void soundNameChanged(const Sound &sound);
|
void soundNameChanged(const Sound &sound, const QString &oldName);
|
||||||
void backgroundNameChanged(const Background &background);
|
void backgroundNameChanged(const Background &background, const QString &oldName);
|
||||||
void pathNameChanged(const Path &path);
|
void pathNameChanged(const Path &path, const QString &oldName);
|
||||||
void scriptNameChanged(const Script &script);
|
void scriptNameChanged(const Script &script, const QString &oldName);
|
||||||
void fontNameChanged(const Font &font);
|
void fontNameChanged(const Font &font, const QString &oldName);
|
||||||
void timeLineNameChanged(const TimeLine &font);
|
void timeLineNameChanged(const TimeLine &font, const QString &oldName);
|
||||||
void objectNameChanged(const Object &font);
|
void objectNameChanged(const Object &font, const QString &oldName);
|
||||||
void roomNameChanged(const Room &font);
|
void roomNameChanged(const Room &font, const QString &oldName);
|
||||||
|
|
||||||
|
void spritePixmapsChanged(const Sprite &sprite);
|
||||||
|
|
||||||
|
void objectSpriteNameChanged(const Object &object, const QString &oldSpriteName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename T> QVariant dataFor(const QModelIndex &index, int role) const;
|
template<typename T> QVariant dataFor(const QModelIndex &index, int role) const;
|
||||||
@@ -97,7 +105,11 @@ private:
|
|||||||
template<typename T> bool setDataFor(const QModelIndex &index, const QVariant &value, int role);
|
template<typename T> bool setDataFor(const QModelIndex &index, const QVariant &value, int role);
|
||||||
template<typename T> std::optional<bool> insertRowsFor(int row, int count, const QModelIndex &parent);
|
template<typename T> std::optional<bool> insertRowsFor(int row, int count, const QModelIndex &parent);
|
||||||
template<typename T> std::optional<bool> removeRowsFor(int row, int count, const QModelIndex &parent);
|
template<typename T> std::optional<bool> removeRowsFor(int row, int count, const QModelIndex &parent);
|
||||||
template<typename T> void emitNameChanged(const T &entry);
|
template<typename T> void onBeforeRemove(const T &entry);
|
||||||
|
template<typename T> void emitAboutToBeRemoved(const T &entry);
|
||||||
|
template<typename T> void onBeforeRename(const T &entry, const QString &newName);
|
||||||
|
template<typename T> void onAfterRename(const T &entry, const QString &oldName);
|
||||||
|
template<typename T> void emitNameChanged(const T &entry, const QString &oldName);
|
||||||
template<typename T> static QString nameTempateFor();
|
template<typename T> static QString nameTempateFor();
|
||||||
|
|
||||||
ProjectContainer *m_project{};
|
ProjectContainer *m_project{};
|
||||||
|
@@ -49,6 +49,12 @@
|
|||||||
<property name="contextMenuPolicy">
|
<property name="contextMenuPolicy">
|
||||||
<enum>Qt::CustomContextMenu</enum>
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>32</width>
|
||||||
|
<height>32</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
Reference in New Issue
Block a user