Cogs.Core
InspectorGuiHelper.h
1#pragma once
2
3#include "../CustomRenderer/ImguiRenderer.h"
4
5#include "Foundation/Reflection/TypeDatabase.h"
6
7#include <span>
8#include <string_view>
9
10namespace Cogs
11{
12 namespace Core
13 {
14 extern std::string guiWindowTitle;
15 extern std::vector<size_t> guiIdsStack;
16
18 {
19 public:
20 explicit ScopedIndent(float spacing = 0.0f) : spacing(spacing)
21 {
22 ImGui::Indent(spacing);
23 }
24
26 {
27 ImGui::Unindent(spacing);
28 }
29
30 private:
31 float spacing = 0;
32 };
33
34 void guiBegin(const std::string & title, bool * show);
35 void guiEnd();
36 std::string getUniqueHeader(const std::string & header);
37
38 // append the bytesize with appropriate unit (b, kb, mb or gb)
39 void appendBytesize(std::string& out, size_t byteSize);
40
41 // Case invariant search for 'substr' in string 'str'.
42 bool containsInvariantCase(std::string_view str, std::string_view substr);
43
51 bool findHierarchyWithMatch(const Cogs::ComponentModel::Entity& entity, std::string_view entityNamePattern, std::string_view componentNamePattern);
52
53 struct Texture;
54 COGSCORE_DLL_API void showTexture(const Context * context, class Renderer * renderer, Texture * texture, bool showTitle = false);
55 COGSCORE_DLL_API void showRenderTexture(const Context * context, class Renderer * renderer, const struct RenderTexture * texture, bool showTitle = false);
56
57 COGSCORE_DLL_API bool showMatrix(const std::string & header, glm::mat4& m);
58
60 template<typename T>
61 bool showEnum(const std::string & header, T& currentItem);
62
65 template<typename T>
66 bool showArray1D(const std::string & header, std::span<T> array);
67
68 template<typename T>
69 bool showArray2D(const std::string & header, std::span<T> array);
70
71 template<typename T>
72 bool showArray3D(const std::string & header, std::span<T> array);
73
74 template<typename T>
75 bool showArray4D(const std::string & header, std::span<T> array);
76
77 COGSCORE_DLL_API bool showArray3D(const std::string & header, std::span<glm::vec3> array);
78
79 struct Mesh;
80 COGSCORE_DLL_API void showMesh(const Context * context, Mesh * mesh, const std::string & header);
81
82 struct MaterialOptions;
83 COGSCORE_DLL_API void showMaterialOptions(const Context * context, MaterialOptions * options, const std::string & header);
84
85 struct MaterialInstance;
86 COGSCORE_DLL_API void showMaterialVariants(MaterialInstance* material);
87
88 COGSCORE_DLL_API void showMaterialProperties(MaterialInstance* material);
89
90 COGSCORE_DLL_API void showMaterialInstance(const Context * context, struct MaterialInstance * material, const std::string & header);
91
92 struct Model;
93 COGSCORE_DLL_API void showModel(const Context * context, Model * model, const std::string & header);
94 }
95}
96
97template<typename T>
98bool Cogs::Core::showEnum(const std::string & header, T & currentItem)
99{
100 auto & type = Cogs::Reflection::TypeDatabase::getType<T>();
101 size_t enums = type.getNumEnumerators();
102 std::vector<const char *> enumNames(enums);
103 std::vector<int> enumValues(enums);
104
105 int currentIndex = 0;
106 for (size_t i = 0; i < enums; ++i) {
107 enumNames[i] = type.getEnumerator(i)->getName().c_str();
108 enumValues[i] = type.getEnumerator(i)->getValue();
109
110 if (enumValues[i] == static_cast<int>(currentItem)) {
111 currentIndex = static_cast<int>(i);
112 }
113 }
114
115 if (ImGui::Combo(header.c_str(), &currentIndex, enumNames.data(), static_cast<int>(enumNames.size()))) {
116 currentItem = static_cast<T>(enumValues[currentIndex]);
117 return true;
118 }
119
120 return false;
121}
122
123template<typename T>
124bool Cogs::Core::showArray1D(const std::string & header, std::span<T> array)
125{
126 ImGui::PushID(array.data());
127
128 bool changed = false;
129
130 if (array.empty()) {
131 ImGui::Text("%s: Empty", header.c_str());
132 } else {
133 if (ImGui::TreeNode((header + " [size=" + std::to_string(array.size()) + "]").c_str())) {
134 ScopedIndent si;
135
136 for (size_t i = 0; i < array.size(); i++) {
137 auto label = std::to_string(i);
138
139 if constexpr (std::is_same_v<T, const uint16_t>) {
140 ImGui::Text("%s: %u", label.c_str(), array[i]);
141 }
142 else if constexpr (std::is_same_v<T, uint16_t>) {
143 int value = static_cast<int>(array[i]);
144 if (ImGui::DragInt(label.c_str(), &value)) {
145 changed = true;
146 array[i] = static_cast<uint16_t>(value);
147 }
148 }
149 else if constexpr (std::is_same_v<T, const int32_t>) {
150 ImGui::Text("%s: %d", label.c_str(), array[i]);
151 }
152 else if constexpr (std::is_same_v<T, int32_t>) {
153 if (ImGui::DragInt(label.c_str(), &array[i])) {
154 changed = true;
155 }
156 }
157 else if constexpr (std::is_same_v<T, const uint32_t>) {
158 ImGui::Text("%s: %u", label.c_str(), array[i]);
159 }
160 else if constexpr (std::is_same_v<T, uint32_t>) {
161 int value = static_cast<int>(array[i]);
162 if (ImGui::DragInt(label.c_str(), &value)) {
163 changed = true;
164 array[i] = static_cast<uint32_t>(value);
165 }
166 }
167 else if constexpr (std::is_same_v<T, const float> || std::is_same_v<T, const double>) {
168 ImGui::Text("%s: %f", label.c_str(), array[i]);
169 }
170 else if constexpr (std::is_same_v<T, const float> || std::is_same_v<T, const double>) {
171 float value = static_cast<float>(array[i]);
172 if (ImGui::DragFloat(label.c_str(), &value)) {
173 array[i] = value;
174 changed = true;
175 }
176 }
177 else if constexpr (true) {
178 // Unhandled.
179 // assert(false);
180 }
181 }
182
183 ImGui::TreePop();
184 }
185 }
186
187 ImGui::PopID();
188
189 return changed;
190}
191
192template<typename T>
193bool Cogs::Core::showArray2D(const std::string & header, std::span<T> array)
194{
195 ImGui::PushID(array.data());
196
197 bool changed = false;
198
199 if (array.empty()) {
200 ImGui::Text("%s: Empty", header.c_str());
201 } else {
202 if (ImGui::TreeNode((header + " [size=" + std::to_string(array.size()) + "]").c_str())) {
203 ScopedIndent si;
204
205 for (size_t i = 0; i < array.size(); i+=2) {
206 auto label = std::to_string(i);
207
208 if constexpr (std::is_same_v<T, float>) {
209 if (ImGui::DragFloat2(label.c_str(), &array[i])) {
210 changed = true;
211 }
212 } else if constexpr (std::is_same_v<T, int>) {
213 if (ImGui::DragInt2(label.c_str(), &array[i])) {
214 changed = true;
215 }
216 }
217 else if constexpr (true) {
218 // Unhandled.
219 // assert(false);
220 }
221 }
222
223 ImGui::TreePop();
224 }
225 }
226
227 ImGui::PopID();
228
229 return changed;
230}
231
232template<typename T>
233bool Cogs::Core::showArray3D(const std::string & header, std::span<T> array)
234{
235 ImGui::PushID(array.data());
236
237 bool changed = false;
238
239 if (array.empty()) {
240 ImGui::Text("%s: Empty", header.c_str());
241 } else {
242 if (ImGui::TreeNode((header + " [size=" + std::to_string(array.size()) + "]").c_str())) {
243 ScopedIndent si;
244
245 for (size_t i = 0; i < array.size(); i+=3) {
246 auto label = std::to_string(i);
247
248 if constexpr (std::is_same_v<T, float>) {
249 if (ImGui::DragFloat3(label.c_str(), &array[i])) {
250 changed = true;
251 }
252 } else if constexpr (std::is_same_v<T, int>) {
253 if (ImGui::DragInt3(label.c_str(), &array[i])) {
254 changed = true;
255 }
256 }
257 else if constexpr (true) {
258 // Unhandled.
259 // assert(false);
260 }
261 }
262
263 ImGui::TreePop();
264 }
265 }
266
267 ImGui::PopID();
268
269 return changed;
270}
271
272template<typename T>
273bool Cogs::Core::showArray4D(const std::string & header, std::span<T> array)
274{
275 ImGui::PushID(array.data());
276
277 bool changed = false;
278
279 if (array.empty()) {
280 ImGui::Text("%s: Empty", header.c_str());
281 } else {
282 if (ImGui::TreeNode((header + " [size=" + std::to_string(array.size()) + "]").c_str())) {
283 ScopedIndent si;
284
285 for (size_t i = 0; i < array.size(); i+=4) {
286 auto label = std::to_string(i);
287
288 if constexpr (std::is_same_v<T, float>) {
289 if (ImGui::DragFloat4(label.c_str(), &array[i])) {
290 changed = true;
291 }
292 } else if constexpr (std::is_same_v<T, int>) {
293 if (ImGui::DragInt4(label.c_str(), &array[i])) {
294 changed = true;
295 }
296 }
297 else if constexpr (true) {
298 // Unhandled.
299 // assert(false);
300 }
301 }
302
303 ImGui::TreePop();
304 }
305 }
306
307 ImGui::PopID();
308
309 return changed;
310}
Container for components, providing composition of dynamic entities.
Definition: Entity.h:18
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
Core renderer system.
Definition: Renderer.h:28
bool findHierarchyWithMatch(const Cogs::ComponentModel::Entity &entity, std::string_view entityNamePattern, std::string_view componentNamePattern)
bool showEnum(const std::string &header, T &currentItem)
Show enumerator with edit option.
bool showArray1D(const std::string &header, std::span< T > array)
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
Material instances represent a specialized Material combined with state for all its buffers and prope...
Defines options for rendering using a material instance.
Meshes contain streams of vertex data in addition to index data and options defining geometry used fo...
Definition: Mesh.h:265
Model resources define a template for a set of connected entities, with resources such as meshes,...
Definition: Model.h:56
Texture resources contain raster bitmap data to use for texturing.
Definition: Texture.h:91