summaryrefslogtreecommitdiffhomepage
path: root/editor/inspect.cpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-02-24 07:17:20 +0100
committerStanislaw Halik <sthalik@misaki.pl>2023-02-24 07:17:20 +0100
commit87c89034894eae06c68e261f5a48c36b8f676b0d (patch)
tree4af67599ac9bac4faccb7ecdeb5debe0622a6dbe /editor/inspect.cpp
parentbad2f1a530b82879dab4c4cff065aab6b1f711c8 (diff)
wip
Diffstat (limited to 'editor/inspect.cpp')
-rw-r--r--editor/inspect.cpp101
1 files changed, 81 insertions, 20 deletions
diff --git a/editor/inspect.cpp b/editor/inspect.cpp
index 02e658b9..bd1329e0 100644
--- a/editor/inspect.cpp
+++ b/editor/inspect.cpp
@@ -3,6 +3,7 @@
#include "compat/defs.hpp"
#include "entity/accessor.hpp"
#include "imgui-raii.hpp"
+#include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/String.h>
#include <Corrade/Containers/StringIterable.h>
#include <Magnum/Math/Vector.h>
@@ -42,11 +43,32 @@ using namespace entities;
template<typename T> requires std::is_integral_v<T> constexpr bool eqv(T a, T b) { return a == b; }
inline bool eqv(float a, float b) { return std::fabs(a - b) < 1e-8f; }
+inline bool eqv(const String& a, const String& b) { return a == b; }
template<typename T, std::size_t N> constexpr bool eqv(const Math::Vector<N, T>& a, const Math::Vector<N, T>& b) { return a == b; }
-template<typename T> void do_inspect_field(void* datum, const erased_accessor& accessor, field_repr repr)
+int corrade_string_resize_callback(ImGuiInputTextCallbackData* data)
{
- fm_assert(accessor.check_field_type<T>());
+ if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
+ {
+ auto* my_str = reinterpret_cast<String*>(data->UserData);
+ fm_assert(my_str->begin() == data->Buf);
+ String tmp = std::move(*my_str);
+ *my_str = String{ValueInit, (std::size_t)data->BufSize};
+ auto len = std::min(tmp.size(), my_str->size());
+ for (std::size_t i = 0; i < len; i++)
+ (*my_str)[i] = tmp[i];
+ data->Buf = my_str->begin();
+ }
+ return 0;
+}
+
+template<typename T>
+void do_inspect_field(void* datum, const erased_accessor& accessor, field_repr repr,
+ const ArrayView<const std::pair<StringView, std::size_t>>& list)
+{
+ if (list.isEmpty())
+ fm_assert(accessor.check_field_type<T>());
+ fm_assert(!list.isEmpty() == (repr == field_repr::cbx));
bool should_disable;
@@ -65,7 +87,13 @@ template<typename T> void do_inspect_field(void* datum, const erased_accessor& a
accessor.read_fun(datum, accessor.reader, &value);
auto orig = value;
- if constexpr(std::is_same_v<T, bool>)
+ if constexpr(std::is_same_v<T, String>)
+ {
+ ret = ImGui::InputText(label.data(), value.begin(), value.size(), ImGuiInputTextFlags_CallbackResize, corrade_string_resize_callback, &value);
+ if (auto max_len = accessor.get_max_length(datum); value.size() > max_len)
+ value = value.prefix(max_len);
+ }
+ else if constexpr(std::is_same_v<T, bool>)
ret = ImGui::Checkbox(label.data(), &value);
else if constexpr (!is_magnum_vector<T>)
{
@@ -74,9 +102,33 @@ template<typename T> void do_inspect_field(void* datum, const erased_accessor& a
T step = 1, *step_ = !std::is_floating_point_v<T> ? &step : nullptr;
switch (repr)
{
+ default: fm_warn_once("invalid repr enum value '%zu'", (std::size_t)repr); break;
case field_repr::input: ret = ImGui::InputScalar(label.data(), igdt, &value, &step_); break;
case field_repr::slider: ret = ImGui::SliderScalar(label.data(), igdt, &value, &min, &max); break;
case field_repr::drag: ret = ImGui::DragScalar(label.data(), igdt, &value, 1, &min, &max); break;
+ case field_repr::cbx: {
+ if constexpr(std::is_integral_v<T>)
+ {
+ const char* preview = "<invalid>";
+ const auto old_value = (std::size_t)static_cast<std::make_unsigned_t<T>>(value);
+ for (const auto& [str, x] : list)
+ if (x == old_value)
+ {
+ preview = str.data();
+ break;
+ }
+ for (auto b = begin_combo(label.data(), preview);
+ const auto& [str, x] : list)
+ {
+ const bool is_selected = x == (std::size_t)old_value;
+ if (ImGui::Selectable(str.data(), is_selected))
+ value = T(x);
+ if (is_selected)
+ ImGui::SetItemDefaultFocus();
+ }
+ break;
+ }
+ }
}
value = std::clamp(value, min, max);
}
@@ -88,6 +140,9 @@ template<typename T> void do_inspect_field(void* datum, const erased_accessor& a
T step = T(U(1)), *step_ = !std::is_floating_point_v<U> ? &step : nullptr;
switch (repr)
{
+ default:
+ fm_warn_once("invalid repr enum value '%zu'", (std::size_t)repr);
+ break;
case field_repr::input:
ret = ImGui::InputScalarN(label.data(), igdt, &value, T::Size, &step_);
break;
@@ -111,29 +166,34 @@ template<typename T> void do_inspect_field(void* datum, const erased_accessor& a
} // namespace
-#define MAKE_SPEC(type, repr) \
- template<> \
- void inspect_field<type>(void* datum, const erased_accessor& accessor) { \
- do_inspect_field<type>(datum, accessor, (repr)); \
+#define MAKE_SPEC(type, repr) \
+ template<> \
+ void inspect_field<type>(void* datum, const erased_accessor& accessor, \
+ const ArrayView<const std::pair<StringView, std::size_t>>& list) \
+ { \
+ do_inspect_field<type>(datum, accessor, (repr), list); \
}
-#define MAKE_SPEC2(type, repr) \
- template<> \
- void inspect_field<field_repr_<type, field_repr, repr>>(void* datum, const erased_accessor& accessor) { \
- do_inspect_field<type>(datum, accessor, (repr)); \
+#define MAKE_SPEC2(type, repr) \
+ template<> \
+ void inspect_field<field_repr_<type, field_repr, repr>>(void* datum, const erased_accessor& accessor, \
+ const ArrayView<const std::pair<StringView, std::size_t>>& list) \
+ { \
+ do_inspect_field<type>(datum, accessor, (repr), list); \
}
-#define MAKE_SPEC_REPRS(type) \
- MAKE_SPEC2(type, field_repr::input) \
- MAKE_SPEC2(type, field_repr::slider) \
- MAKE_SPEC2(type, field_repr::drag) \
+#define MAKE_SPEC_REPRS(type) \
+ MAKE_SPEC2(type, field_repr::input) \
+ MAKE_SPEC2(type, field_repr::slider) \
+ MAKE_SPEC2(type, field_repr::drag) \
MAKE_SPEC(type, field_repr::input)
-#define MAKE_SPEC_REPRS2(type) \
- MAKE_SPEC_REPRS(Math::Vector2<type>) \
- MAKE_SPEC_REPRS(Math::Vector3<type>) \
- MAKE_SPEC_REPRS(Math::Vector4<type>) \
- MAKE_SPEC_REPRS(type)
+#define MAKE_SPEC_REPRS2(type) \
+ MAKE_SPEC_REPRS(Math::Vector2<type>) \
+ MAKE_SPEC_REPRS(Math::Vector3<type>) \
+ MAKE_SPEC_REPRS(Math::Vector4<type>) \
+ MAKE_SPEC_REPRS(type) \
+ MAKE_SPEC2(type, field_repr::cbx)
MAKE_SPEC_REPRS2(std::uint8_t)
MAKE_SPEC_REPRS2(std::int8_t)
@@ -143,5 +203,6 @@ MAKE_SPEC_REPRS2(std::uint32_t)
MAKE_SPEC_REPRS2(std::int32_t)
MAKE_SPEC_REPRS2(float)
MAKE_SPEC(bool, field_repr::input)
+MAKE_SPEC(String, field_repr::input)
} // namespace floormat::entities