diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-02-24 07:17:20 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-02-24 07:17:20 +0100 |
commit | 87c89034894eae06c68e261f5a48c36b8f676b0d (patch) | |
tree | 4af67599ac9bac4faccb7ecdeb5debe0622a6dbe /editor/inspect.cpp | |
parent | bad2f1a530b82879dab4c4cff065aab6b1f711c8 (diff) |
wip
Diffstat (limited to 'editor/inspect.cpp')
-rw-r--r-- | editor/inspect.cpp | 101 |
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 |