1 /* |
|
2 * LDForge: LDraw parts authoring CAD |
|
3 * Copyright (C) 2013 - 2020 Teemu Piippo |
|
4 * |
|
5 * This program is free software: you can redistribute it and/or modify |
|
6 * it under the terms of the GNU General Public License as published by |
|
7 * the Free Software Foundation, either version 3 of the License, or |
|
8 * (at your option) any later version. |
|
9 * |
|
10 * This program is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 * GNU General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License |
|
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
17 */ |
|
18 |
|
19 #pragma once |
|
20 #include "model.h" |
|
21 |
|
22 /** |
|
23 * @brief Provides an interface for editing a model such that signals are emitted for each edit done. |
|
24 * User edits to models should always be done through this class. |
|
25 */ |
|
26 class ModelEditor : public QObject |
|
27 { |
|
28 Q_OBJECT |
|
29 public: |
|
30 ModelEditor(Model& model); |
|
31 ~ModelEditor(); |
|
32 template<typename T, typename... Args> |
|
33 ldraw::Id<T> append(Args&&... args); |
|
34 ldraw::id_t append(std::unique_ptr<ldraw::Object>&& object); |
|
35 template<typename T, typename... Args> |
|
36 ldraw::Id<T> insert(int position, Args&&... args); |
|
37 void remove(int position); |
|
38 template<ldraw::Property property> |
|
39 void setObjectProperty(ldraw::id_t id, const ldraw::PropertyType<property>& value); |
|
40 auto setObjectProperty(ldraw::id_t id, ldraw::Property property, const QVariant& value) |
|
41 -> ldraw::Object::SetPropertyResult; |
|
42 void setObjectPoint(ldraw::id_t id, int pointId, const glm::vec3& value); |
|
43 template<typename T, typename Fn> |
|
44 bool modifyObject(ldraw::Id<T> id, Fn&& function); |
|
45 template<typename T, typename Fn> |
|
46 bool modifyObjectAt(int position, Fn&& function); |
|
47 const Model& model(); |
|
48 Q_SIGNALS: |
|
49 void objectAdded(int position); |
|
50 void objectModified(int position); |
|
51 void objectRemoved(ldraw::id_t id); |
|
52 private: |
|
53 QSet<ldraw::id_t> modifiedObjects; |
|
54 Model& storedModel; |
|
55 }; |
|
56 |
|
57 template<ldraw::Property Property> |
|
58 void ModelEditor::setObjectProperty(const ldraw::id_t id, const ldraw::PropertyType<Property>& value) |
|
59 { |
|
60 this->modifyObject(id, [&](ldraw::Object* object){ |
|
61 object->setProperty<Property>(value); |
|
62 }); |
|
63 } |
|
64 |
|
65 template<typename T, typename... Args> |
|
66 ldraw::Id<T> ModelEditor::append(Args&&... args) |
|
67 { |
|
68 return this->storedModel.append<T>(args...); |
|
69 } |
|
70 |
|
71 template<typename T, typename... Args> |
|
72 ldraw::Id<T> ModelEditor::insert(int position, Args&&... args) |
|
73 { |
|
74 return this->storedModel.insert<T>(position, args...); |
|
75 } |
|
76 |
|
77 template<typename T, typename Fn> |
|
78 bool ModelEditor::modifyObject(ldraw::Id<T> id, Fn&& function) |
|
79 { |
|
80 QModelIndex index = this->model().find(id); |
|
81 return this->modifyObjectAt<T>(index.row(), function); |
|
82 } |
|
83 |
|
84 template<typename T, typename Fn> |
|
85 bool ModelEditor::modifyObjectAt(int position, Fn&& function) |
|
86 { |
|
87 if (position >= 0 and position < this->model().size()) |
|
88 { |
|
89 T* object = dynamic_cast<T*>(this->storedModel[position]); |
|
90 if (object != nullptr) |
|
91 { |
|
92 Q_EMIT this->objectModified(position); |
|
93 function(object); |
|
94 return true; |
|
95 } |
|
96 } |
|
97 return false; |
|
98 } |
|