src/model.h

changeset 333
07e65a4c6611
parent 328
3ea38fd469ca
child 336
e07425ac5834
equal deleted inserted replaced
332:ae7f7fbb9cda 333:07e65a4c6611
20 #include <QAbstractListModel> 20 #include <QAbstractListModel>
21 #include <memory> 21 #include <memory>
22 #include "src/basics.h" 22 #include "src/basics.h"
23 #include "src/colors.h" 23 #include "src/colors.h"
24 24
25 #include <QTextDocument>
26 using Model = QTextDocument;
27
25 struct SubfileReference 28 struct SubfileReference
26 { 29 {
27 QString name; 30 QString name;
28 glm::mat4 transformation; 31 glm::mat4 transformation;
29 bool inverted = false;
30 }; 32 };
31 33
32 template<typename T> 34 template<typename T>
33 struct Colored : T 35 struct Colored : T
34 { 36 {
114 Quadrilateral, 116 Quadrilateral,
115 ConditionalEdge>; 117 ConditionalEdge>;
116 118
117 using PolygonElement = Colored<PlainPolygonElement>; 119 using PolygonElement = Colored<PlainPolygonElement>;
118 120
119 template<typename T>
120 struct remove_color {};
121
122 template<typename T>
123 struct remove_color<Colored<T>> { using type = T; };
124
125 template<typename T>
126 struct remove_color<Colored<T>&> { using type = T&; };
127
128 template<typename T>
129 struct remove_color<const Colored<T>&> { using type = const T&; };
130
131 template<typename T>
132 struct remove_color<Colored<T>&&> { using type = T&&; };
133
134 template<typename T>
135 using remove_color_t = typename remove_color<T>::type;
136
137 static_assert(std::is_same_v<remove_color_t<Colored<Triangle>>, Triangle>);
138 static_assert(std::is_same_v<remove_color_t<Colored<Triangle>&>, Triangle&>);
139 static_assert(std::is_same_v<remove_color_t<const Colored<Triangle>&>, const Triangle&>);
140
141 template<typename T>
142 constexpr remove_color_t<T&&> extract_colored(T&& x)
143 {
144 return static_cast<remove_color_t<T&&>>(x);
145 }
146
147 template<typename Ret, typename Fn1, typename Fn2, typename Fn3, typename Fn4, typename T> 121 template<typename Ret, typename Fn1, typename Fn2, typename Fn3, typename Fn4, typename T>
148 constexpr auto visitPolygon(Fn1&& f1, Fn2&& f2, Fn3&& f3, Fn4&& f4, T&& element) 122 constexpr auto visitPolygon(Fn1&& f1, Fn2&& f2, Fn3&& f3, Fn4&& f4, T&& element)
149 { 123 {
150 if (std::holds_alternative<LineSegment>(element)) { 124 if (std::holds_alternative<LineSegment>(element)) {
151 return f1(std::get<LineSegment>(element)); 125 return f1(std::get<LineSegment>(element));
189 func(cedge.p2); 163 func(cedge.p2);
190 func(cedge.c1); 164 func(cedge.c1);
191 func(cedge.c2); 165 func(cedge.c2);
192 }, 166 },
193 element); 167 element);
194 }
195
196 QString modelElementToString(const ModelElement& element);
197 struct ElementId
198 {
199 std::int32_t value;
200 constexpr auto operator<=>(const ElementId& other) const = default;
201 };
202
203 constexpr auto qHash(ElementId id)
204 {
205 return qHash(id.value);
206 }
207
208 class Model : public QAbstractListModel
209 {
210 Q_OBJECT
211 struct Entry {
212 ModelElement data;
213 ElementId id;
214 };
215 std::vector<Entry> body;
216 std::map<ElementId, std::size_t> positions;
217 ElementId runningId = {1};
218 public:
219 explicit Model(QObject* parent);
220 virtual ~Model();
221 ElementId append(const ModelElement& value);
222 const ModelElement& at(std::size_t position) const;
223 ElementId idAt(std::size_t position) const;
224 void assignAt(std::size_t position, const ModelElement& element);
225 std::optional<std::size_t> find(ElementId id) const;
226 void remove(std::size_t index);
227 int rowCount(const QModelIndex&) const override;
228 QVariant data(const QModelIndex& index, int role) const override;
229 const ModelElement& operator[](std::size_t index) const;
230 std::size_t size() const;
231 void clear();
232 auto operator[](const std::size_t index) {
233 struct {
234 Model& model;
235 const std::size_t index;
236 operator const ModelElement&() {
237 return model.at(index);
238 }
239 auto& operator=(const ModelElement& newData) {
240 model.assignAt(index, newData);
241 return *this;
242 }
243 const auto* operator&() {
244 return &(this->operator const ModelElement&());
245 }
246 } result{*this, index};
247 return result;
248 }
249 };
250
251 void save(const Model& model, QTextStream* stream);
252 void updateHeaderNameField(Model& model, const QString &name);
253
254 template<typename T>
255 void iterate(const Model& model, std::function<void(const T&)> fn)
256 {
257 for (std::size_t i = 0; i < model.size(); ++i) {
258 if (std::holds_alternative<T>(model[i])) {
259 fn(std::get<T>(model[i]));
260 }
261 }
262 } 168 }
263 169
264 constexpr Colored<LineSegment> edge(const glm::vec3& p1, const glm::vec3& p2) 170 constexpr Colored<LineSegment> edge(const glm::vec3& p1, const glm::vec3& p2)
265 { 171 {
266 return Colored<LineSegment>{{.p1 = p1, .p2 = p2}, EDGE_COLOR}; 172 return Colored<LineSegment>{{.p1 = p1, .p2 = p2}, EDGE_COLOR};

mercurial