diff --git a/framework/imgui/CMakeLists.txt b/framework/imgui/CMakeLists.txt index c308e7f..e7bd102 100644 --- a/framework/imgui/CMakeLists.txt +++ b/framework/imgui/CMakeLists.txt @@ -21,6 +21,7 @@ target_link_libraries(imgui_service ################## imgui_widgets add_library(imgui_widgets + ./src/mm/imgui/widgets/scalar_range.hpp ./src/mm/imgui/widgets/knob.hpp ./src/mm/imgui/widgets/plot_radar.hpp ./src/mm/imgui/widgets/camera.hpp @@ -43,6 +44,7 @@ add_library(imgui_widgets ############ + ./src/mm/imgui/widgets/scalar_range.cpp ./src/mm/imgui/widgets/knob.cpp ./src/mm/imgui/widgets/plot_radar.cpp ./src/mm/imgui/widgets/camera.cpp @@ -69,6 +71,7 @@ target_link_libraries(imgui_widgets engine common_components + std_utils ) ################## imgui_tools diff --git a/framework/imgui/src/mm/imgui/widgets/scalar_range.cpp b/framework/imgui/src/mm/imgui/widgets/scalar_range.cpp new file mode 100644 index 0000000..2eebcbd --- /dev/null +++ b/framework/imgui/src/mm/imgui/widgets/scalar_range.cpp @@ -0,0 +1,48 @@ +#include "./scalar_range.hpp" + +namespace MM::ImGuiWidgets { + + // unsigned int + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, uint8_t v_min , uint8_t v_max) { + return DragScalarRange2EXT(label, ImGuiDataType_U8, &range.min(), &range.max(), 0.1f, v_min, v_max); + } + + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, uint16_t v_min , uint16_t v_max) { + return DragScalarRange2EXT(label, ImGuiDataType_U16, &range.min(), &range.max(), 0.1f, v_min, v_max); + } + + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, uint32_t v_min , uint32_t v_max) { + return DragScalarRange2EXT(label, ImGuiDataType_U32, &range.min(), &range.max(), 0.1f, v_min, v_max); + } + + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, uint64_t v_min , uint64_t v_max) { + return DragScalarRange2EXT(label, ImGuiDataType_U64, &range.min(), &range.max(), 0.1f, v_min, v_max); + } + + // signed int + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, int8_t v_min , int8_t v_max) { + return DragScalarRange2EXT(label, ImGuiDataType_S8, &range.min(), &range.max(), 0.1f, v_min, v_max); + } + + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, int16_t v_min , int16_t v_max) { + return DragScalarRange2EXT(label, ImGuiDataType_S16, &range.min(), &range.max(), 0.1f, v_min, v_max); + } + + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, int32_t v_min , int32_t v_max) { + return DragScalarRange2EXT(label, ImGuiDataType_S32, &range.min(), &range.max(), 0.1f, v_min, v_max); + } + + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, int64_t v_min , int64_t v_max) { + return DragScalarRange2EXT(label, ImGuiDataType_S64, &range.min(), &range.max(), 0.1f, v_min, v_max); + } + +} // MM::ImGuiWidgets + diff --git a/framework/imgui/src/mm/imgui/widgets/scalar_range.hpp b/framework/imgui/src/mm/imgui/widgets/scalar_range.hpp new file mode 100644 index 0000000..31c9cef --- /dev/null +++ b/framework/imgui/src/mm/imgui/widgets/scalar_range.hpp @@ -0,0 +1,75 @@ +#pragma once + +#include + +#include +#include +#include +#include + +namespace MM::ImGuiWidgets { + + // cedits: this code is copied from DearImGui and modified + + // NB: You likely want to specify the ImGuiSliderFlags_AlwaysClamp when using this. + template + bool DragScalarRange2EXT(const char* label, ImGuiDataType data_type, T* v_current_min, T* v_current_max, float v_speed = 1.f, T v_min = {}, T v_max = {}, const char* format = NULL, const char* format_max = NULL, ImGuiSliderFlags flags = 0) + { + ImGuiContext& g = *ImGui::GetCurrentContext(); + auto* window = g.CurrentWindow; + if (window->SkipItems) + return false; + + ImGui::PushID(label); + ImGui::BeginGroup(); + ImGui::PushMultiItemsWidths(2, ImGui::CalcItemWidth()); + + T min_min = (v_min >= v_max) ? std::numeric_limits::min() : v_min; + T min_max = (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max); + ImGuiSliderFlags min_flags = flags | ((min_min == min_max) ? ImGuiSliderFlags_ReadOnly : 0); + bool value_changed = ImGui::DragScalar("##min", data_type, v_current_min, v_speed, &min_min, &min_max, format, min_flags); + ImGui::PopItemWidth(); + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); + + T max_min = (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min); + T max_max = (v_min >= v_max) ? std::numeric_limits::max() : v_max; + ImGuiSliderFlags max_flags = flags | ((max_min == max_max) ? ImGuiSliderFlags_ReadOnly : 0); + value_changed |= ImGui::DragScalar("##max", data_type, v_current_max, v_speed, &max_min, &max_max, format_max ? format_max : format, max_flags); + ImGui::PopItemWidth(); + ImGui::SameLine(0, g.Style.ItemInnerSpacing.x); + + ImGui::TextEx(label, ImGui::FindRenderedTextEnd(label)); + ImGui::EndGroup(); + ImGui::PopID(); + return value_changed; + } + + // scalar range + template + bool DragScalarRange2(const char* label, ScalarRange2& range, T v_min = {}, T v_max = {}); + + // specializations + // unsigned int + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, uint8_t v_min , uint8_t v_max); + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, uint16_t v_min , uint16_t v_max); + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, uint32_t v_min , uint32_t v_max); + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, uint64_t v_min , uint64_t v_max); + + // signed int + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, int8_t v_min , int8_t v_max); + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, int16_t v_min , int16_t v_max); + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, int32_t v_min , int32_t v_max); + template<> + bool DragScalarRange2(const char* label, ScalarRange2& range, int64_t v_min , int64_t v_max); + + // TODO: float, double + +} // MM::ImGuiWidgets + diff --git a/framework/imgui/test/widget_test.cpp b/framework/imgui/test/widget_test.cpp index 722937d..2aebf35 100644 --- a/framework/imgui/test/widget_test.cpp +++ b/framework/imgui/test/widget_test.cpp @@ -1,3 +1,5 @@ +#include "mm/imgui/widgets/scalar_range.hpp" +#include "mm/scalar_range2.hpp" #include #include @@ -57,6 +59,8 @@ TEST(imgui_widgets, basic) { ImGui::SameLine(); MM::ImGuiWidgets::KnobFloat("knob2", &knob_test, 0.f, 1.f, 0.f, false); + static MM::ScalarRange2 range {0, 100}; + MM::ImGuiWidgets::DragScalarRange2("range", range); } ImGui::End(); }