Wed, 25 May 2022 20:36:34 +0300
Fix pick() picking from weird places on the screen with high DPI scaling
glReadPixels reads data from the frame buffer, which contains data after
high DPI scaling, so any reads to that need to take this scaling into account
24 | 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 | ||
3 | 19 | #pragma once |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
6
diff
changeset
|
20 | #include <QAbstractListModel> |
3 | 21 | #include <memory> |
22 | #include "main.h" | |
23 | #include "header.h" | |
14 | 24 | #include "linetypes/object.h" |
141 | 25 | #include "linetypes/metacommand.h" |
21 | 26 | #include "gl/common.h" |
3 | 27 | |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
6
diff
changeset
|
28 | enum class HeaderProperty |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
6
diff
changeset
|
29 | { |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
6
diff
changeset
|
30 | Name |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
6
diff
changeset
|
31 | }; |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
6
diff
changeset
|
32 | |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
6
diff
changeset
|
33 | class Model : public QAbstractListModel |
3 | 34 | { |
35 | Q_OBJECT | |
36 | public: | |
21 | 37 | Model(QObject* parent = nullptr); |
5 | 38 | Model(const Model&) = delete; |
150
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
39 | |
3 | 40 | int size() const; |
133
e39326ee48dc
Begin work on edit history
Teemu Piippo <teemu@hecknology.net>
parents:
117
diff
changeset
|
41 | ldraw::id_t at(int index) const; |
8
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
6
diff
changeset
|
42 | int rowCount(const QModelIndex&) const override; |
44679e468ba9
major update with many things
Teemu Piippo <teemu@hecknology.net>
parents:
6
diff
changeset
|
43 | QVariant data(const QModelIndex& index, int role) const override; |
151 | 44 | ldraw::Object* findObjectById(const ldraw::id_t id); |
45 | const ldraw::Object* findObjectById(const ldraw::id_t id) const; | |
150
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
46 | QModelIndex find(ldraw::id_t id) const; |
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
47 | ldraw::id_t idAt(const QModelIndex& index) const; |
141 | 48 | template<typename R> |
116 | 49 | const R* get(ldraw::Id<R> id) const; |
50 | template<typename R> | |
51 | struct Get2Result | |
52 | { | |
53 | QModelIndex index; | |
54 | const R* object; | |
55 | }; | |
56 | template<typename R> | |
57 | Get2Result<R> get2(ldraw::Id<R> id) const; | |
150
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
58 | ldraw::Object* operator[](int index); |
151 | 59 | const ldraw::Object* operator[](int index) const; |
35
98906a94732f
renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
60 | using ModelObjectPointer = std::unique_ptr<ldraw::Object>; |
3 | 61 | template<typename T, typename... Args> |
73
97df974b5ed5
ldraw::Id is now templated for extra type safety
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
62 | ldraw::Id<T> append(Args&&... args); |
152 | 63 | ldraw::id_t append(ModelObjectPointer&& object); |
3 | 64 | template<typename T, typename... Args> |
76
7c4a63a02632
finished splitQuadrilateral theoretically (untested)
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
65 | ldraw::Id<T> insert(std::size_t position, Args&&... args); |
7c4a63a02632
finished splitQuadrilateral theoretically (untested)
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
66 | void remove(int position); |
152 | 67 | void emitDataChangedSignal(int position); |
68 | private: | |
3 | 69 | bool modified = false; |
70 | std::vector<ModelObjectPointer> body; | |
173
8a3047468994
Fix performance issues in Model::find
Teemu Piippo <teemu@hecknology.net>
parents:
152
diff
changeset
|
71 | mutable std::map<ldraw::id_t, std::size_t> objectsById; |
8a3047468994
Fix performance issues in Model::find
Teemu Piippo <teemu@hecknology.net>
parents:
152
diff
changeset
|
72 | mutable bool needObjectsByIdRebuild = false; |
3 | 73 | }; |
74 | ||
151 | 75 | void save(const Model& model, QIODevice *device); |
141 | 76 | |
77 | /** | |
138 | 78 | * @brief Calls the specified function to all matching objects in the model |
79 | * @tparam R Type of LDraw line type object to filter by | |
80 | * @param fn Function to call. | |
117 | 81 | */ |
82 | template<typename R, typename Fn> | |
151 | 83 | void applyToModel(const Model& model, Fn&& f) |
117 | 84 | { |
151 | 85 | for (int i = 0; i < model.size(); i += 1) |
117 | 86 | { |
151 | 87 | const ldraw::Object* object = model[i]; |
88 | const R* subobject = dynamic_cast<const R*>(object); | |
117 | 89 | if (subobject != nullptr) |
90 | { | |
91 | f(subobject); | |
92 | } | |
93 | } | |
94 | } | |
95 | ||
3 | 96 | template<typename T, typename... Args> |
73
97df974b5ed5
ldraw::Id is now templated for extra type safety
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
97 | ldraw::Id<T> Model::append(Args&&... args) |
3 | 98 | { |
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
81
diff
changeset
|
99 | const int position = static_cast<int>(this->body.size()); |
112 | 100 | Q_EMIT beginInsertRows({}, position, position); |
3 | 101 | this->body.push_back(std::make_unique<T>(args...)); |
35
98906a94732f
renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
102 | ldraw::Object* pointer = this->body.back().get(); |
173
8a3047468994
Fix performance issues in Model::find
Teemu Piippo <teemu@hecknology.net>
parents:
152
diff
changeset
|
103 | this->objectsById[pointer->id] = this->body.size() - 1; |
112 | 104 | Q_EMIT endInsertRows(); |
76
7c4a63a02632
finished splitQuadrilateral theoretically (untested)
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
105 | return ldraw::Id<T>{pointer->id.value}; |
3 | 106 | } |
107 | ||
108 | template<typename T, typename... Args> | |
111
1f42c03fafca
Draw tool actually adds objects now
Teemu Piippo <teemu@hecknology.net>
parents:
81
diff
changeset
|
109 | ldraw::Id<T> Model::insert(const std::size_t position, Args&&... args) |
3 | 110 | { |
112 | 111 | Q_EMIT beginInsertRows({}, position, position); |
76
7c4a63a02632
finished splitQuadrilateral theoretically (untested)
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
112 | this->body.insert(std::begin(this->body) + position, std::make_unique<T>(args...)); |
35
98906a94732f
renamed the linetypes namespace to ldraw namespace and added more structures to it
Teemu Piippo <teemu@hecknology.net>
parents:
26
diff
changeset
|
113 | ldraw::Object* pointer = this->body[position].get(); |
173
8a3047468994
Fix performance issues in Model::find
Teemu Piippo <teemu@hecknology.net>
parents:
152
diff
changeset
|
114 | this->objectsById[pointer->id] = position; |
112 | 115 | Q_EMIT endInsertRows(); |
76
7c4a63a02632
finished splitQuadrilateral theoretically (untested)
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
116 | return ldraw::Id<T>{pointer->id.value}; |
3 | 117 | } |
73
97df974b5ed5
ldraw::Id is now templated for extra type safety
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
118 | |
97df974b5ed5
ldraw::Id is now templated for extra type safety
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
119 | template<typename R> |
116 | 120 | const R* Model::get(ldraw::Id<R> id) const |
73
97df974b5ed5
ldraw::Id is now templated for extra type safety
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
121 | { |
116 | 122 | return this->get2(id).object; |
123 | } | |
124 | ||
125 | template<typename R> | |
126 | Model::Get2Result<R> Model::get2(const ldraw::Id<R> id) const | |
127 | { | |
128 | Get2Result<R> result; | |
150
b6cbba6e29a1
extract polygon cache out of Model
Teemu Piippo <teemu@hecknology.net>
parents:
148
diff
changeset
|
129 | result.index = this->find(id); |
116 | 130 | if (result.index.isValid()) |
76
7c4a63a02632
finished splitQuadrilateral theoretically (untested)
Teemu Piippo <teemu@hecknology.net>
parents:
73
diff
changeset
|
131 | { |
151 | 132 | result.object = static_cast<const R*>((*this)[result.index.row()]); |
81
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
76
diff
changeset
|
133 | } |
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
76
diff
changeset
|
134 | else |
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
76
diff
changeset
|
135 | { |
116 | 136 | result.object = nullptr; |
81
62373840e33a
object editor widgets start to form up
Teemu Piippo <teemu@hecknology.net>
parents:
76
diff
changeset
|
137 | } |
116 | 138 | return result; |
73
97df974b5ed5
ldraw::Id is now templated for extra type safety
Teemu Piippo <teemu@hecknology.net>
parents:
51
diff
changeset
|
139 | } |