Implement mask sprite in objects

This commit is contained in:
2024-01-09 20:55:13 +01:00
parent ef2a9e9fb8
commit 2e7d6ad6c5
7 changed files with 99 additions and 46 deletions

View File

@@ -23,8 +23,10 @@ ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel
m_eventsModel{std::make_unique<ObjectEventsModel>(m_events, m_collisionEvents)}, m_eventsModel{std::make_unique<ObjectEventsModel>(m_events, m_collisionEvents)},
m_menuSprites{new QMenu{this}}, m_menuSprites{new QMenu{this}},
m_menuParents{new QMenu{this}}, m_menuParents{new QMenu{this}},
m_menuMaskSprites{new QMenu{this}},
m_spriteName{object.spriteName}, m_spriteName{object.spriteName},
m_parentName{object.parentName} m_parentName{object.parentName},
m_maskSpriteName{object.maskSpriteName}
{ {
m_ui->setupUi(this); m_ui->setupUi(this);
@@ -38,9 +40,11 @@ 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);
m_ui->lineEditParent->setText(m_parentName.isEmpty() ? tr("<no parent>") : m_parentName); m_ui->lineEditParent->setText(m_parentName.isEmpty() ? tr("<no parent>") : m_parentName);
m_ui->lineEditMask->setText(m_maskSpriteName.isEmpty() ? tr("<same as sprite>") : m_maskSpriteName);
updateSpritePreview(); updateSpritePreview();
m_ui->toolButtonSprite->setMenu(m_menuSprites); m_ui->toolButtonSprite->setMenu(m_menuSprites);
m_ui->toolButtonParent->setMenu(m_menuParents); m_ui->toolButtonParent->setMenu(m_menuParents);
m_ui->toolButtonMask->setMenu(m_menuMaskSprites);
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);
m_ui->spinBoxDepth->setValue(m_object.depth); m_ui->spinBoxDepth->setValue(m_object.depth);
@@ -48,6 +52,7 @@ ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel
m_ui->lineEditSprite->setMenu(m_menuSprites); m_ui->lineEditSprite->setMenu(m_menuSprites);
m_ui->lineEditParent->setMenu(m_menuParents); m_ui->lineEditParent->setMenu(m_menuParents);
m_ui->lineEditMask->setMenu(m_menuMaskSprites);
m_ui->listViewEvents->setModel(m_eventsModel.get()); m_ui->listViewEvents->setModel(m_eventsModel.get());
@@ -101,6 +106,8 @@ ObjectPropertiesDialog::ObjectPropertiesDialog(Object &object, ProjectTreeModel
this, &ObjectPropertiesDialog::spritesMenuAboutToShow); this, &ObjectPropertiesDialog::spritesMenuAboutToShow);
connect(m_menuParents, &QMenu::aboutToShow, connect(m_menuParents, &QMenu::aboutToShow,
this, &ObjectPropertiesDialog::parentsMenuAboutToShow); this, &ObjectPropertiesDialog::parentsMenuAboutToShow);
connect(m_menuMaskSprites, &QMenu::aboutToShow,
this, &ObjectPropertiesDialog::maskSpritesMenuAboutToShow);
connect(m_ui->listViewEvents->selectionModel(), &QItemSelectionModel::currentChanged, connect(m_ui->listViewEvents->selectionModel(), &QItemSelectionModel::currentChanged,
this, &ObjectPropertiesDialog::currentEventChanged); this, &ObjectPropertiesDialog::currentEventChanged);
@@ -142,6 +149,7 @@ void ObjectPropertiesDialog::accept()
m_object.depth = m_ui->spinBoxDepth->value(); m_object.depth = m_ui->spinBoxDepth->value();
m_object.persistent = m_ui->checkBoxPersistent->isChecked(); m_object.persistent = m_ui->checkBoxPersistent->isChecked();
m_object.parentName = m_parentName; m_object.parentName = m_parentName;
m_object.maskSpriteName = m_maskSpriteName;
m_object.events = std::move(m_events); m_object.events = std::move(m_events);
m_object.collisionEvents = std::move(m_collisionEvents); m_object.collisionEvents = std::move(m_collisionEvents);
@@ -284,18 +292,24 @@ void ObjectPropertiesDialog::objectNameChanged(const Object &object, const QStri
void ObjectPropertiesDialog::spriteNameChanged(const Sprite &sprite, const QString &oldName) void ObjectPropertiesDialog::spriteNameChanged(const Sprite &sprite, const QString &oldName)
{ {
if (m_spriteName.isEmpty()) if (!m_spriteName.isEmpty() && m_spriteName == oldName)
return; {
if (m_spriteName != oldName)
return;
m_spriteName = sprite.name; m_spriteName = sprite.name;
{ {
QSignalBlocker blocker{m_ui->lineEditSprite}; QSignalBlocker blocker{m_ui->lineEditSprite};
m_ui->lineEditSprite->setText(sprite.name); m_ui->lineEditSprite->setText(sprite.name);
} }
updateSpritePreview(); updateSpritePreview();
}
if (!m_maskSpriteName.isEmpty() && m_maskSpriteName == oldName)
{
m_maskSpriteName = sprite.name;
{
QSignalBlocker blocker{m_ui->lineEditMask};
m_ui->lineEditMask->setText(sprite.name);
}
}
} }
void ObjectPropertiesDialog::objectAboutToBeRemoved(const Object &object) void ObjectPropertiesDialog::objectAboutToBeRemoved(const Object &object)
@@ -318,6 +332,15 @@ void ObjectPropertiesDialog::spriteAboutToBeRemoved(const Sprite &sprite)
} }
m_ui->labelSpritePreview->setPixmap(QPixmap{}); m_ui->labelSpritePreview->setPixmap(QPixmap{});
} }
if (!m_maskSpriteName.isEmpty() && m_maskSpriteName == sprite.name)
{
m_maskSpriteName.clear();
{
QSignalBlocker blocker{m_ui->lineEditMask};
m_ui->lineEditMask->setText(tr("<same as sprite>"));
}
}
} }
void ObjectPropertiesDialog::spritePixmapsChanged(const Sprite &sprite) void ObjectPropertiesDialog::spritePixmapsChanged(const Sprite &sprite)
@@ -365,6 +388,17 @@ void ObjectPropertiesDialog::parentsMenuAboutToShow()
} }
} }
void ObjectPropertiesDialog::maskSpritesMenuAboutToShow()
{
m_menuMaskSprites->clear();
m_menuMaskSprites->addAction(tr("<same as sprite>"), this, &ObjectPropertiesDialog::clearMaskSprite);
for (const auto &sprite : m_projectModel.project()->sprites)
m_menuMaskSprites->addAction(sprite.pixmaps.empty() ? QPixmap{} : sprite.pixmaps.front(),
sprite.name,
this,
[&sprite,this](){ setMaskSprite(sprite); });
}
void ObjectPropertiesDialog::currentEventChanged(const QModelIndex &index) void ObjectPropertiesDialog::currentEventChanged(const QModelIndex &index)
{ {
if (index.isValid()) if (index.isValid())
@@ -435,6 +469,20 @@ void ObjectPropertiesDialog::setParent(const Object &object)
changed(); changed();
} }
void ObjectPropertiesDialog::clearMaskSprite()
{
m_maskSpriteName.clear();
m_ui->lineEditMask->setText(tr("<same as sprite>"));
changed();
}
void ObjectPropertiesDialog::setMaskSprite(const Sprite &sprite)
{
m_maskSpriteName = sprite.name;
m_ui->lineEditMask->setText(sprite.name);
changed();
}
void ObjectPropertiesDialog::updateTitle() void ObjectPropertiesDialog::updateTitle()
{ {
setWindowTitle(tr("Object Properties: %0%1") setWindowTitle(tr("Object Properties: %0%1")

View File

@@ -43,6 +43,7 @@ private slots:
void spritesMenuAboutToShow(); void spritesMenuAboutToShow();
void parentsMenuAboutToShow(); void parentsMenuAboutToShow();
void maskSpritesMenuAboutToShow();
void currentEventChanged(const QModelIndex &index); void currentEventChanged(const QModelIndex &index);
void eventsContextMenuRequested(const QPoint &pos); void eventsContextMenuRequested(const QPoint &pos);
void rowsInserted(const QModelIndex &parent, int first); void rowsInserted(const QModelIndex &parent, int first);
@@ -53,6 +54,9 @@ private slots:
void clearParent(); void clearParent();
void setParent(const Object &object); void setParent(const Object &object);
void clearMaskSprite();
void setMaskSprite(const Sprite &sprite);
private: private:
void updateTitle(); void updateTitle();
void updateSpritePreview(); void updateSpritePreview();
@@ -71,9 +75,11 @@ private:
QMenu * const m_menuSprites; QMenu * const m_menuSprites;
QMenu * const m_menuParents; QMenu * const m_menuParents;
QMenu * const m_menuMaskSprites;
QString m_spriteName; QString m_spriteName;
QString m_parentName; QString m_parentName;
QString m_maskSpriteName;
bool m_unsavedChanges{}; bool m_unsavedChanges{};
}; };

View File

@@ -244,7 +244,7 @@
<item row="3" column="1"> <item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
<widget class="QLineEdit" name="lineEditMask"> <widget class="QLineEditWithMenu" name="lineEditMask">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed"> <sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>

View File

@@ -283,9 +283,8 @@ template<> void ProjectTreeModel::onBeforeRemove<Sprite>(const Sprite &sprite)
{ {
for (auto iter = std::begin(m_project->objects); iter != std::end(m_project->objects); iter++) for (auto iter = std::begin(m_project->objects); iter != std::end(m_project->objects); iter++)
{ {
if (iter->spriteName != sprite.name) if (iter->spriteName == sprite.name)
continue; {
auto oldSpriteName = std::move(iter->spriteName); auto oldSpriteName = std::move(iter->spriteName);
iter->spriteName.clear(); iter->spriteName.clear();
@@ -294,6 +293,12 @@ template<> void ProjectTreeModel::onBeforeRemove<Sprite>(const Sprite &sprite)
emit objectSpriteNameChanged(*iter, std::move(oldSpriteName)); emit objectSpriteNameChanged(*iter, std::move(oldSpriteName));
} }
if (iter->maskSpriteName == sprite.name)
{
iter->maskSpriteName.clear();
}
}
} }
template<> void ProjectTreeModel::onBeforeRemove<Object>(const Object &object) template<> void ProjectTreeModel::onBeforeRemove<Object>(const Object &object)
@@ -330,9 +335,8 @@ template<> void ProjectTreeModel::onAfterRename<Sprite>(const Sprite &sprite, co
{ {
for (auto &object : m_project->objects) for (auto &object : m_project->objects)
{ {
if (object.spriteName != oldName) if (object.spriteName == oldName)
continue; {
auto oldSpriteName = std::move(object.spriteName); auto oldSpriteName = std::move(object.spriteName);
object.spriteName = sprite.name; object.spriteName = sprite.name;
@@ -342,6 +346,12 @@ template<> void ProjectTreeModel::onAfterRename<Sprite>(const Sprite &sprite, co
emit objectSpriteNameChanged(object, std::move(oldSpriteName)); emit objectSpriteNameChanged(object, std::move(oldSpriteName));
} }
if (object.maskSpriteName == oldName)
{
object.maskSpriteName = sprite.name;
}
}
} }
template<> void ProjectTreeModel::onBeforeRename<Object>(const Object &object, const QString &newName) template<> void ProjectTreeModel::onBeforeRename<Object>(const Object &object, const QString &newName)

View File

@@ -40,6 +40,11 @@ ActionsContainerWidget::ActionsContainerWidget(QWidget *parent) :
emit changed(); emit changed();
} }
}); });
m_ui->toolButtonMoveFixed->setAction(MoveFixedAction{});
m_ui->toolButtonMoveFree->setAction(MoveFreeAction{});
m_ui->toolButtonMoveTowards->setAction(MoveTowardsAction{});
m_ui->toolButtonExecuteCode->setAction(ExecuteCodeAction{});
} }
ActionsContainerWidget::~ActionsContainerWidget() = default; ActionsContainerWidget::~ActionsContainerWidget() = default;

View File

@@ -232,26 +232,8 @@ struct Object
int depth{}; int depth{};
bool persistent{}; bool persistent{};
QString parentName; QString parentName;
events_container_t events { QString maskSpriteName;
{ events_container_t events;
EventType::Create,
ActionsContainer {
Action { MoveFixedAction{} },
Action { MoveFreeAction{} },
Action { MoveTowardsAction{} },
Action { ExecuteCodeAction{} }
}
},
{
EventType::Destroy,
ActionsContainer {
Action { ExecuteCodeAction{} },
Action { MoveTowardsAction{} },
Action { MoveFreeAction{} },
Action { MoveFixedAction{} }
}
}
};
collision_events_container_t collisionEvents; collision_events_container_t collisionEvents;
}; };

View File

@@ -341,6 +341,7 @@ QDataStream &operator<<(QDataStream &ds, const Object &object)
<< object.depth << object.depth
<< object.persistent << object.persistent
<< object.parentName << object.parentName
<< object.maskSpriteName
<< object.events << object.events
<< object.collisionEvents; << object.collisionEvents;
return ds; return ds;
@@ -355,6 +356,7 @@ QDataStream &operator>>(QDataStream &ds, Object &object)
>> object.depth >> object.depth
>> object.persistent >> object.persistent
>> object.parentName >> object.parentName
>> object.maskSpriteName
>> object.events >> object.events
>> object.collisionEvents; >> object.collisionEvents;
return ds; return ds;