INSTINCT Code Coverage Report


Directory: src/
File: internal/gui/widgets/KeyedMatrix.hpp
Date: 2025-02-07 16:54:41
Exec Total Coverage
Lines: 0 55 0.0%
Functions: 0 12 0.0%
Branches: 0 118 0.0%

Line Branch Exec Source
1 // This file is part of INSTINCT, the INS Toolkit for Integrated
2 // Navigation Concepts and Training by the Institute of Navigation of
3 // the University of Stuttgart, Germany.
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9 /// @file KeyedMatrix.hpp
10 /// @brief Widgets related to KeyedMatrices
11 /// @author T. Topp (topp@ins.uni-stuttgart.de)
12 /// @date 2023-08-04
13
14 #pragma once
15
16 #include <imgui.h>
17 #include <application.h>
18 #include "util/Container/KeyedMatrix.hpp"
19
20 namespace NAV::gui::widgets
21 {
22
23 /// @brief Shows GUI elements to display the coefficients of a matrix
24 /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>.
25 /// @tparam RowKeyType Type of the key used for row lookup
26 /// @tparam ColKeyType Type of the key used for col lookup
27 /// @tparam Rows Number of rows, or \b Dynamic
28 /// @tparam Cols Number of columns, or \b Dynamic
29 /// @param[in] label Label to display beside. Has to be unique (use # to hide text afterwards to append an uid)
30 /// @param[in] matrix Pointer to the matrix to display
31 /// @param[in] tableHeight Height of the Table to show scrollbar afterwards (-1 means no scrollbar)
32 /// @param[in] tableFlags Flags to modify the Table behaviour
33 template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols>
34 void KeyedMatrixView(const char* label, const KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols>* matrix,
35 float tableHeight = -1.0F,
36 ImGuiTableFlags tableFlags = ImGuiTableFlags_Borders
37 | ImGuiTableFlags_NoHostExtendX
38 | ImGuiTableFlags_SizingFixedFit
39 | ImGuiTableFlags_ScrollX
40 | ImGuiTableFlags_ScrollY)
41 {
42 ImGui::PushFont(Application::MonoFont());
43 float height = ImGui::GetTextLineHeightWithSpacing() * static_cast<float>(matrix->rows() + 1);
44 ImVec2 outer_size = ImVec2(0.0F, tableHeight > 0.0F ? std::min(tableHeight, height) : height);
45 if (ImGui::BeginTable(label, static_cast<int>(matrix->cols()) + 1, tableFlags, outer_size))
46 {
47 ImGui::TableSetupScrollFreeze(1, 1);
48 ImGui::TableSetupColumn(""); // Colum headers
49
50 constexpr size_t colMinLength = 10UL;
51 std::vector<size_t> colKeysLength;
52 colKeysLength.reserve(static_cast<size_t>(matrix->cols()));
53
54 for (int64_t col = 0; col < matrix->cols(); col++)
55 {
56 std::string colKeyStr = fmt::format("{}", matrix->colKeys().at(static_cast<size_t>(col)));
57 colKeysLength.push_back(colKeyStr.length());
58 ImGui::TableSetupColumn(colKeyStr.c_str());
59 }
60 ImGui::TableHeadersRow();
61
62 for (int64_t row = 0; row < matrix->rows(); row++)
63 {
64 ImGui::TableNextColumn();
65 ImGui::TextUnformatted(fmt::format("{}", matrix->rowKeys().at(static_cast<size_t>(row))).c_str());
66 ImU32 cell_bg_color = ImGui::GetColorU32(ImGui::GetStyle().Colors[ImGuiCol_TableHeaderBg]);
67 ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color);
68
69 for (int64_t col = 0; col < matrix->cols(); col++)
70 {
71 ImGui::TableNextColumn();
72
73 auto colLength = std::max(colKeysLength.at(static_cast<size_t>(col)), colMinLength);
74 std::string text = fmt::format(" {:> {}.{}g}", (*matrix)(NAV::all, NAV::all)(row, col), colLength, colLength - 2);
75 if (text.length() > colLength)
76 {
77 text = fmt::format(" {:> {}.{}g}", (*matrix)(NAV::all, NAV::all)(row, col), colLength, colLength - 6);
78 }
79 ImGui::TextUnformatted(text.c_str());
80 if (ImGui::IsItemHovered())
81 {
82 ImGui::SetTooltip("%.8g", (*matrix)(NAV::all, NAV::all)(row, col));
83 }
84 }
85 }
86 ImGui::EndTable();
87 }
88 ImGui::PopFont();
89 }
90
91 /// @brief Shows GUI elements to display the coefficients of a matrix
92 /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>.
93 /// @tparam RowKeyType Type of the key used for row lookup
94 /// @tparam Rows Number of rows, or \b Dynamic
95 /// @param[in] label Label to display beside. Has to be unique (use # to hide text afterwards to append an uid)
96 /// @param[in] matrix Pointer to the matrix to display
97 /// @param[in] tableHeight Height of the Table to show scrollbar afterwards (-1 means no scrollbar)
98 /// @param[in] tableFlags Flags to modify the Table behaviour
99 template<typename Scalar, typename RowKeyType, int Rows>
100 void KeyedVectorView(const char* label, const KeyedVector<Scalar, RowKeyType, Rows>* matrix,
101 float tableHeight = -1.0F,
102 ImGuiTableFlags tableFlags = ImGuiTableFlags_Borders
103 | ImGuiTableFlags_NoHostExtendX
104 | ImGuiTableFlags_SizingFixedFit
105 | ImGuiTableFlags_ScrollY)
106 {
107 ImGui::PushFont(Application::MonoFont());
108 float height = ImGui::GetTextLineHeightWithSpacing() * static_cast<float>(matrix->rows());
109 ImVec2 outer_size = ImVec2(0.0F, tableHeight > 0.0F ? std::min(tableHeight, height) : height);
110 if (ImGui::BeginTable(label, 2, tableFlags, outer_size))
111 {
112 ImGui::TableSetupScrollFreeze(1, 0);
113
114 constexpr size_t colLength = 10UL;
115
116 for (int64_t row = 0; row < matrix->rows(); row++)
117 {
118 ImGui::TableNextColumn();
119 ImGui::TextUnformatted(fmt::format("{}", matrix->rowKeys().at(static_cast<size_t>(row))).c_str());
120 ImU32 cell_bg_color = ImGui::GetColorU32(ImGui::GetStyle().Colors[ImGuiCol_TableHeaderBg]);
121 ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color);
122
123 ImGui::TableNextColumn();
124
125 std::string text = fmt::format(" {:> {}.{}g}", (*matrix)(NAV::all)(row), colLength, colLength - 2);
126 if (text.length() > colLength)
127 {
128 text = fmt::format(" {:> {}.{}g}", (*matrix)(NAV::all)(row), colLength, colLength - 6);
129 }
130 ImGui::TextUnformatted(text.c_str());
131 if (ImGui::IsItemHovered())
132 {
133 ImGui::SetTooltip("%.8g", (*matrix)(NAV::all)(row));
134 }
135 }
136 ImGui::EndTable();
137 }
138 ImGui::PopFont();
139 }
140
141 /// @brief Shows GUI elements to display the coefficients of a matrix
142 /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>.
143 /// @tparam ColKeyType Type of the key used for col lookup
144 /// @tparam Cols Number of columns, or \b Dynamic
145 /// @param[in] label Label to display beside. Has to be unique (use # to hide text afterwards to append an uid)
146 /// @param[in] matrix Pointer to the matrix to display
147 /// @param[in] tableFlags Flags to modify the Table behaviour
148 template<typename Scalar, typename ColKeyType, int Cols>
149 void KeyedRowVectorView(const char* label, const KeyedRowVector<Scalar, ColKeyType, Cols>* matrix,
150 ImGuiTableFlags tableFlags = ImGuiTableFlags_Borders
151 | ImGuiTableFlags_NoHostExtendX
152 | ImGuiTableFlags_SizingFixedFit
153 | ImGuiTableFlags_ScrollX)
154 {
155 ImGui::PushFont(Application::MonoFont());
156 ImVec2 outer_size = ImVec2(0.0F, ImGui::GetTextLineHeightWithSpacing() * 2.0F);
157 if (ImGui::BeginTable(label, static_cast<int>(matrix->cols()) + 1, tableFlags, outer_size))
158 {
159 ImGui::TableSetupScrollFreeze(0, 1);
160
161 constexpr size_t colMinLength = 10UL;
162 std::vector<size_t> colKeysLength;
163 colKeysLength.reserve(static_cast<size_t>(matrix->cols()));
164
165 for (int64_t col = 0; col < matrix->cols(); col++)
166 {
167 std::string colKeyStr = fmt::format("{}", matrix->colKeys().at(static_cast<size_t>(col)));
168 colKeysLength.push_back(colKeyStr.length());
169 ImGui::TableSetupColumn(colKeyStr.c_str());
170 }
171 ImGui::TableHeadersRow();
172
173 for (int64_t col = 0; col < matrix->cols(); col++)
174 {
175 ImGui::TableNextColumn();
176
177 auto colLength = std::max(colKeysLength.at(static_cast<size_t>(col)), colMinLength);
178 std::string text = fmt::format(" {:> {}.{}g}", (*matrix)(NAV::all)(col), colLength, colLength - 2);
179 if (text.length() > colLength)
180 {
181 text = fmt::format(" {:> {}.{}g}", (*matrix)(NAV::all)(col), colLength, colLength - 6);
182 }
183 ImGui::TextUnformatted(text.c_str());
184 if (ImGui::IsItemHovered())
185 {
186 ImGui::SetTooltip("%.8g", (*matrix)(NAV::all)(col));
187 }
188 }
189
190 ImGui::EndTable();
191 }
192 ImGui::PopFont();
193 }
194
195 #if defined(__GNUC__) || defined(__clang__)
196 #pragma GCC diagnostic push
197 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
198 #endif
199
200 /// @brief Shows GUI elements to modify the coefficients of a matrix with
201 /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>.
202 /// @tparam RowKeyType Type of the key used for row lookup
203 /// @tparam ColKeyType Type of the key used for col lookup
204 /// @tparam Rows Number of rows, or \b Dynamic
205 /// @tparam Cols Number of columns, or \b Dynamic
206 /// @param[in] label Label to display beside. Has to be unique (use # to hide text afterwards to append an uid)
207 /// @param[in, out] matrix Pointer to the matrix to modify
208 /// @param[in] tableHeight Height of the Table to show scrollbar afterwards (-1 means no scrollbar)
209 /// @param[in] tableFlags Flags to modify the Table behaviour
210 /// @param[in] step Step size of the InputText
211 /// @param[in] step_fast Fast step size of the InputText
212 /// @param[in] format Printf format to display the value with
213 /// @param[in] inputTextFlags InputText flags to modify the behavior of the input fields
214 /// @return True if the value was changed
215 template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols>
216 bool InputKeyedMatrix(const char* label, KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols>* matrix,
217 float tableHeight = -1.0F,
218 ImGuiTableFlags tableFlags = ImGuiTableFlags_Borders
219 | ImGuiTableFlags_NoHostExtendX
220 | ImGuiTableFlags_SizingFixedFit
221 | ImGuiTableFlags_ScrollX
222 | ImGuiTableFlags_ScrollY,
223 double step = 0.0, double step_fast = 0.0,
224 const char* format = "%.4g",
225 ImGuiInputTextFlags inputTextFlags = ImGuiInputTextFlags_None)
226 {
227 bool changed = false;
228 ImGui::PushFont(Application::MonoFont());
229 const float TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x;
230 float height = ImGui::GetTextLineHeightWithSpacing()
231 + (ImGui::GetTextLineHeightWithSpacing() + 1.5F * ImGui::GetStyle().ItemSpacing.y)
232 * static_cast<float>(matrix->rows());
233 ImVec2 outer_size = ImVec2(0.0F, tableHeight > 0.0F ? std::min(tableHeight, height) : height);
234 if (ImGui::BeginTable(label, static_cast<int>(matrix->cols()) + 1, tableFlags, outer_size))
235 {
236 ImGui::TableSetupScrollFreeze(1, 1);
237 ImGui::TableSetupColumn(""); // Colum headers
238
239 constexpr size_t colMinLength = 11UL;
240 std::vector<size_t> colKeysLength;
241 colKeysLength.reserve(static_cast<size_t>(matrix->cols()));
242
243 for (int64_t col = 0; col < matrix->cols(); col++)
244 {
245 std::string colKeyStr = fmt::format("{}", matrix->colKeys().at(static_cast<size_t>(col)));
246 colKeysLength.push_back(colKeyStr.length());
247 ImGui::TableSetupColumn(colKeyStr.c_str());
248 }
249 ImGui::TableHeadersRow();
250
251 for (int64_t row = 0; row < matrix->rows(); row++)
252 {
253 ImGui::TableNextColumn();
254 ImGui::TextUnformatted(fmt::format("{}", matrix->rowKeys().at(static_cast<size_t>(row))).c_str());
255 ImU32 cell_bg_color = ImGui::GetColorU32(ImGui::GetStyle().Colors[ImGuiCol_TableHeaderBg]);
256 ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color);
257
258 for (int64_t col = 0; col < matrix->cols(); col++)
259 {
260 ImGui::TableNextColumn();
261
262 auto colLength = std::max(colKeysLength.at(static_cast<size_t>(col)), colMinLength);
263 ImGui::SetNextItemWidth(TEXT_BASE_WIDTH * static_cast<float>(colLength));
264 if (ImGui::InputDouble(fmt::format("##{} ({}, {})", label, row, col).c_str(), &(*matrix)(NAV::all, NAV::all)(row, col), step, step_fast, format, inputTextFlags))
265 {
266 changed = true;
267 }
268 if (ImGui::IsItemHovered())
269 {
270 ImGui::SetTooltip("%.8g", (*matrix)(NAV::all, NAV::all)(row, col));
271 }
272 }
273 }
274 ImGui::EndTable();
275 }
276 ImGui::PopFont();
277
278 return changed;
279 }
280
281 /// @brief Shows GUI elements to modify the coefficients of a matrix with
282 /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>.
283 /// @tparam RowKeyType Type of the key used for row lookup
284 /// @tparam Rows Number of rows, or \b Dynamic
285 /// @param[in] label Label to display beside. Has to be unique (use # to hide text afterwards to append an uid)
286 /// @param[in, out] matrix Pointer to the matrix to modify
287 /// @param[in] tableHeight Height of the Table to show scrollbar afterwards (-1 means no scrollbar)
288 /// @param[in] tableFlags Flags to modify the Table behaviour
289 /// @param[in] step Step size of the InputText
290 /// @param[in] step_fast Fast step size of the InputText
291 /// @param[in] format Printf format to display the value with
292 /// @param[in] inputTextFlags InputText flags to modify the behavior of the input fields
293 /// @return True if the value was changed
294 template<typename Scalar, typename RowKeyType, int Rows>
295 bool InputKeyedVector(const char* label, KeyedVector<Scalar, RowKeyType, Rows>* matrix,
296 float tableHeight = -1.0F,
297 ImGuiTableFlags tableFlags = ImGuiTableFlags_Borders
298 | ImGuiTableFlags_NoHostExtendX
299 | ImGuiTableFlags_SizingFixedFit
300 | ImGuiTableFlags_ScrollY,
301 double step = 0.0, double step_fast = 0.0,
302 const char* format = "%.4g",
303 ImGuiInputTextFlags inputTextFlags = ImGuiInputTextFlags_None)
304 {
305 bool changed = false;
306 ImGui::PushFont(Application::MonoFont());
307 const float TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x;
308 float height = (ImGui::GetTextLineHeightWithSpacing() + 1.5F * ImGui::GetStyle().ItemSpacing.y) * static_cast<float>(matrix->rows());
309 ImVec2 outer_size = ImVec2(0.0F, tableHeight > 0.0F ? std::min(tableHeight, height) : height);
310 if (ImGui::BeginTable(label, 2, tableFlags, outer_size))
311 {
312 ImGui::TableSetupScrollFreeze(1, 0);
313
314 constexpr size_t colLength = 11UL;
315
316 for (int64_t row = 0; row < matrix->rows(); row++)
317 {
318 ImGui::TableNextColumn();
319 ImGui::TextUnformatted(fmt::format("{}", matrix->rowKeys().at(static_cast<size_t>(row))).c_str());
320 ImU32 cell_bg_color = ImGui::GetColorU32(ImGui::GetStyle().Colors[ImGuiCol_TableHeaderBg]);
321 ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color);
322
323 ImGui::TableNextColumn();
324
325 ImGui::SetNextItemWidth(TEXT_BASE_WIDTH * static_cast<float>(colLength));
326 if (ImGui::InputDouble(fmt::format("##{} ({})", label, row).c_str(), &(*matrix)(NAV::all)(row), step, step_fast, format, inputTextFlags))
327 {
328 changed = true;
329 }
330 if (ImGui::IsItemHovered())
331 {
332 ImGui::SetTooltip("%.8g", (*matrix)(NAV::all)(row));
333 }
334 }
335 ImGui::EndTable();
336 }
337 ImGui::PopFont();
338
339 return changed;
340 }
341
342 /// @brief Shows GUI elements to modify the coefficients of a matrix with
343 /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>.
344 /// @tparam ColKeyType Type of the key used for col lookup
345 /// @tparam Cols Number of columns, or \b Dynamic
346 /// @param[in] label Label to display beside. Has to be unique (use # to hide text afterwards to append an uid)
347 /// @param[in, out] matrix Pointer to the matrix to modify
348 /// @param[in] tableFlags Flags to modify the Table behaviour
349 /// @param[in] step Step size of the InputText
350 /// @param[in] step_fast Fast step size of the InputText
351 /// @param[in] format Printf format to display the value with
352 /// @param[in] inputTextFlags InputText flags to modify the behavior of the input fields
353 /// @return True if the value was changed
354 template<typename Scalar, typename ColKeyType, int Cols>
355 bool InputKeyedRowVector(const char* label, KeyedRowVector<Scalar, ColKeyType, Cols>* matrix,
356 ImGuiTableFlags tableFlags = ImGuiTableFlags_Borders
357 | ImGuiTableFlags_NoHostExtendX
358 | ImGuiTableFlags_SizingFixedFit
359 | ImGuiTableFlags_ScrollX,
360 double step = 0.0, double step_fast = 0.0,
361 const char* format = "%.4g",
362 ImGuiInputTextFlags inputTextFlags = ImGuiInputTextFlags_None)
363 {
364 bool changed = false;
365 ImGui::PushFont(Application::MonoFont());
366 const float TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x;
367 ImVec2 outer_size = ImVec2(0.0F, ImGui::GetTextLineHeightWithSpacing()
368 + (ImGui::GetTextLineHeightWithSpacing() + 1.5F * ImGui::GetStyle().ItemSpacing.y));
369 if (ImGui::BeginTable(label, static_cast<int>(matrix->cols()) + 1, tableFlags, outer_size))
370 {
371 ImGui::TableSetupScrollFreeze(0, 1);
372
373 constexpr size_t colMinLength = 11UL;
374 std::vector<size_t> colKeysLength;
375 colKeysLength.reserve(static_cast<size_t>(matrix->cols()));
376
377 for (int64_t col = 0; col < matrix->cols(); col++)
378 {
379 std::string colKeyStr = fmt::format("{}", matrix->colKeys().at(static_cast<size_t>(col)));
380 colKeysLength.push_back(colKeyStr.length());
381 ImGui::TableSetupColumn(colKeyStr.c_str());
382 }
383 ImGui::TableHeadersRow();
384
385 for (int64_t col = 0; col < matrix->cols(); col++)
386 {
387 ImGui::TableNextColumn();
388
389 auto colLength = std::max(colKeysLength.at(static_cast<size_t>(col)), colMinLength);
390 ImGui::SetNextItemWidth(TEXT_BASE_WIDTH * static_cast<float>(colLength));
391 if (ImGui::InputDouble(fmt::format("##{} ({})", label, col).c_str(), &(*matrix)(NAV::all)(col), step, step_fast, format, inputTextFlags))
392 {
393 changed = true;
394 }
395 if (ImGui::IsItemHovered())
396 {
397 ImGui::SetTooltip("%.8g", (*matrix)(NAV::all)(col));
398 }
399 }
400
401 ImGui::EndTable();
402 }
403 ImGui::PopFont();
404
405 return changed;
406 }
407
408 #if defined(__GNUC__) || defined(__clang__)
409 #pragma GCC diagnostic pop
410 #endif
411
412 } // namespace NAV::gui::widgets
413