diff -r e628fc2e0c72 -r 03f8e6d42e13 src/modeleditcontext.h --- a/src/modeleditcontext.h Thu Mar 03 21:13:16 2022 +0200 +++ b/src/modeleditcontext.h Fri Mar 04 11:37:50 2022 +0200 @@ -19,10 +19,16 @@ #pragma once #include "model.h" -class Model::EditContext +/** + * @brief Provides an interface for editing a model such that signals are emitted for each edit done. + * User edits to models should always be done through this class. + */ +class ModelEditor : public QObject { + Q_OBJECT public: - ~EditContext(); + ModelEditor(Model& model); + ~ModelEditor(); template ldraw::Id append(Args&&... args); ldraw::id_t append(std::unique_ptr&& object); @@ -34,51 +40,59 @@ auto setObjectProperty(ldraw::id_t id, ldraw::Property property, const QVariant& value) -> ldraw::Object::SetPropertyResult; void setObjectPoint(ldraw::id_t id, int pointId, const glm::vec3& value); - void invertObject(ldraw::id_t id); - Model& model(); + template + bool modifyObject(ldraw::Id id, Fn&& function); + template + bool modifyObjectAt(int position, Fn&& function); + const Model& model(); +Q_SIGNALS: + void objectAdded(int position); + void objectModified(int position); + void objectRemoved(ldraw::id_t id); private: - EditContext(Model& model); - friend class Model; QSet modifiedObjects; Model& storedModel; }; template -void Model::EditContext::setObjectProperty(const ldraw::id_t id, const ldraw::PropertyType& value) +void ModelEditor::setObjectProperty(const ldraw::id_t id, const ldraw::PropertyType& value) { - ldraw::Object* object = this->model().findObjectById(id); - if (object != nullptr) - { + this->modifyObject(id, [&](ldraw::Object* object){ object->setProperty(value); - modifiedObjects.insert(id); - } + }); } template -ldraw::Id Model::EditContext::append(Args&&... args) +ldraw::Id ModelEditor::append(Args&&... args) { return this->storedModel.append(args...); } template -ldraw::Id Model::EditContext::insert(int position, Args&&... args) +ldraw::Id ModelEditor::insert(int position, Args&&... args) { return this->storedModel.insert(position, args...); } -namespace ldraw +template +bool ModelEditor::modifyObject(ldraw::Id id, Fn&& function) { - /// Determines how quadrilaterals are split into triangles - enum class Diagonal + QModelIndex index = this->model().find(id); + return this->modifyObjectAt(index.row(), function); +} + +template +bool ModelEditor::modifyObjectAt(int position, Fn&& function) +{ + if (position >= 0 and position < this->model().size()) { - Diagonal_13, - Diagonal_24 - }; - - // Splits the specified quadrilateral into triangles. - // If it is not a quadrilateral then no action is performed - auto splitQuadrilateral(Model::EditContext& editor, - quadrilateralid_t quadrilateral_id, - Diagonal splitType = Diagonal::Diagonal_13 - ) -> std::optional>; -} + T* object = dynamic_cast(this->storedModel[position]); + if (object != nullptr) + { + Q_EMIT this->objectModified(position); + function(object); + return true; + } + } + return false; +} \ No newline at end of file