|
@@ -921,7 +921,7 @@ template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
|
|
static bool DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const TYPE v_min, const TYPE v_max, const char* format, float power);
|
|
static bool DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const TYPE v_min, const TYPE v_max, const char* format, float power);
|
|
|
|
|
|
template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
|
|
template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
|
|
-static bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const char* format, float power, ImGuiSliderFlags flags);
|
|
|
|
|
|
+static bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb);
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
@@ -9346,10 +9346,9 @@ static inline float SliderBehaviorCalcRatioFromValue(ImGuiDataType data_type, TY
|
|
|
|
|
|
// FIXME: Move some of the code into SliderBehavior(). Current responsability is larger than what the equivalent DragBehaviorT<> does, we also do some rendering, etc.
|
|
// FIXME: Move some of the code into SliderBehavior(). Current responsability is larger than what the equivalent DragBehaviorT<> does, we also do some rendering, etc.
|
|
template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
|
|
template<typename TYPE, typename SIGNEDTYPE, typename FLOATTYPE>
|
|
-static bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const char* format, float power, ImGuiSliderFlags flags)
|
|
|
|
|
|
+static bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
- ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
const ImGuiStyle& style = g.Style;
|
|
const ImGuiStyle& style = g.Style;
|
|
|
|
|
|
const bool is_horizontal = (flags & ImGuiSliderFlags_Vertical) == 0;
|
|
const bool is_horizontal = (flags & ImGuiSliderFlags_Vertical) == 0;
|
|
@@ -9496,17 +9495,15 @@ static bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType d
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- // Draw
|
|
|
|
|
|
+ // Output grab position so it can be displayed by the caller
|
|
float grab_t = SliderBehaviorCalcRatioFromValue<TYPE,FLOATTYPE>(data_type, *v, v_min, v_max, power, linear_zero_pos);
|
|
float grab_t = SliderBehaviorCalcRatioFromValue<TYPE,FLOATTYPE>(data_type, *v, v_min, v_max, power, linear_zero_pos);
|
|
if (!is_horizontal)
|
|
if (!is_horizontal)
|
|
grab_t = 1.0f - grab_t;
|
|
grab_t = 1.0f - grab_t;
|
|
const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t);
|
|
const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t);
|
|
- ImRect grab_bb;
|
|
|
|
if (is_horizontal)
|
|
if (is_horizontal)
|
|
- grab_bb = ImRect(grab_pos - grab_sz*0.5f, bb.Min.y + grab_padding, grab_pos + grab_sz*0.5f, bb.Max.y - grab_padding);
|
|
|
|
|
|
+ *out_grab_bb = ImRect(grab_pos - grab_sz*0.5f, bb.Min.y + grab_padding, grab_pos + grab_sz*0.5f, bb.Max.y - grab_padding);
|
|
else
|
|
else
|
|
- grab_bb = ImRect(bb.Min.x + grab_padding, grab_pos - grab_sz*0.5f, bb.Max.x - grab_padding, grab_pos + grab_sz*0.5f);
|
|
|
|
- window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding);
|
|
|
|
|
|
+ *out_grab_bb = ImRect(bb.Min.x + grab_padding, grab_pos - grab_sz*0.5f, bb.Max.x - grab_padding, grab_pos + grab_sz*0.5f);
|
|
|
|
|
|
return value_changed;
|
|
return value_changed;
|
|
}
|
|
}
|
|
@@ -9514,34 +9511,28 @@ static bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType d
|
|
// For 32-bits and larger types, slider bounds are limited to half the natural type range.
|
|
// For 32-bits and larger types, slider bounds are limited to half the natural type range.
|
|
// So e.g. an integer Slider between INT_MAX-10 and INT_MAX will fail, but an integer Slider between INT_MAX/2-10 and INT_MAX/2 will be ok.
|
|
// So e.g. an integer Slider between INT_MAX-10 and INT_MAX will fail, but an integer Slider between INT_MAX/2-10 and INT_MAX/2 will be ok.
|
|
// It would be possible to lift that limitation with some work but it doesn't seem to be worth it for sliders.
|
|
// It would be possible to lift that limitation with some work but it doesn't seem to be worth it for sliders.
|
|
-bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power, ImGuiSliderFlags flags)
|
|
|
|
|
|
+bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb)
|
|
{
|
|
{
|
|
- // Draw frame
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
|
|
|
- RenderNavHighlight(bb, id);
|
|
|
|
- RenderFrame(bb.Min, bb.Max, frame_col, true, g.Style.FrameRounding);
|
|
|
|
-
|
|
|
|
switch (data_type)
|
|
switch (data_type)
|
|
{
|
|
{
|
|
case ImGuiDataType_S32:
|
|
case ImGuiDataType_S32:
|
|
IM_ASSERT(*(const ImS32*)v_min >= IM_S32_MIN/2 && *(const ImS32*)v_max <= IM_S32_MAX/2);
|
|
IM_ASSERT(*(const ImS32*)v_min >= IM_S32_MIN/2 && *(const ImS32*)v_max <= IM_S32_MAX/2);
|
|
- return SliderBehaviorT<ImS32, ImS32, float >(bb, id, data_type, (ImS32*)v, *(const ImS32*)v_min, *(const ImS32*)v_max, format, power, flags);
|
|
|
|
|
|
+ return SliderBehaviorT<ImS32, ImS32, float >(bb, id, data_type, (ImS32*)v, *(const ImS32*)v_min, *(const ImS32*)v_max, format, power, flags, out_grab_bb);
|
|
case ImGuiDataType_U32:
|
|
case ImGuiDataType_U32:
|
|
IM_ASSERT(*(const ImU32*)v_min <= IM_U32_MAX/2);
|
|
IM_ASSERT(*(const ImU32*)v_min <= IM_U32_MAX/2);
|
|
- return SliderBehaviorT<ImU32, ImS32, float >(bb, id, data_type, (ImU32*)v, *(const ImU32*)v_min, *(const ImU32*)v_max, format, power, flags);
|
|
|
|
|
|
+ return SliderBehaviorT<ImU32, ImS32, float >(bb, id, data_type, (ImU32*)v, *(const ImU32*)v_min, *(const ImU32*)v_max, format, power, flags, out_grab_bb);
|
|
case ImGuiDataType_S64:
|
|
case ImGuiDataType_S64:
|
|
IM_ASSERT(*(const ImS64*)v_min >= IM_S64_MIN/2 && *(const ImS64*)v_max <= IM_S64_MAX/2);
|
|
IM_ASSERT(*(const ImS64*)v_min >= IM_S64_MIN/2 && *(const ImS64*)v_max <= IM_S64_MAX/2);
|
|
- return SliderBehaviorT<ImS64, ImS64, double>(bb, id, data_type, (ImS64*)v, *(const ImS64*)v_min, *(const ImS64*)v_max, format, power, flags);
|
|
|
|
|
|
+ return SliderBehaviorT<ImS64, ImS64, double>(bb, id, data_type, (ImS64*)v, *(const ImS64*)v_min, *(const ImS64*)v_max, format, power, flags, out_grab_bb);
|
|
case ImGuiDataType_U64:
|
|
case ImGuiDataType_U64:
|
|
IM_ASSERT(*(const ImU64*)v_min <= IM_U64_MAX/2);
|
|
IM_ASSERT(*(const ImU64*)v_min <= IM_U64_MAX/2);
|
|
- return SliderBehaviorT<ImU64, ImS64, double>(bb, id, data_type, (ImU64*)v, *(const ImU64*)v_min, *(const ImU64*)v_max, format, power, flags);
|
|
|
|
|
|
+ return SliderBehaviorT<ImU64, ImS64, double>(bb, id, data_type, (ImU64*)v, *(const ImU64*)v_min, *(const ImU64*)v_max, format, power, flags, out_grab_bb);
|
|
case ImGuiDataType_Float:
|
|
case ImGuiDataType_Float:
|
|
IM_ASSERT(*(const float*)v_min >= -FLT_MAX/2.0f && *(const float*)v_max <= FLT_MAX/2.0f);
|
|
IM_ASSERT(*(const float*)v_min >= -FLT_MAX/2.0f && *(const float*)v_max <= FLT_MAX/2.0f);
|
|
- return SliderBehaviorT<float, float, float >(bb, id, data_type, (float*)v, *(const float*)v_min, *(const float*)v_max, format, power, flags);
|
|
|
|
|
|
+ return SliderBehaviorT<float, float, float >(bb, id, data_type, (float*)v, *(const float*)v_min, *(const float*)v_max, format, power, flags, out_grab_bb);
|
|
case ImGuiDataType_Double:
|
|
case ImGuiDataType_Double:
|
|
IM_ASSERT(*(const double*)v_min >= -DBL_MAX/2.0f && *(const double*)v_max <= DBL_MAX/2.0f);
|
|
IM_ASSERT(*(const double*)v_min >= -DBL_MAX/2.0f && *(const double*)v_max <= DBL_MAX/2.0f);
|
|
- return SliderBehaviorT<double,double,double>(bb, id, data_type, (double*)v, *(const double*)v_min, *(const double*)v_max, format, power, flags);
|
|
|
|
|
|
+ return SliderBehaviorT<double,double,double>(bb, id, data_type, (double*)v, *(const double*)v_min, *(const double*)v_max, format, power, flags, out_grab_bb);
|
|
case ImGuiDataType_COUNT: break;
|
|
case ImGuiDataType_COUNT: break;
|
|
}
|
|
}
|
|
IM_ASSERT(0);
|
|
IM_ASSERT(0);
|
|
@@ -9621,12 +9612,22 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* v, co
|
|
if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id))
|
|
if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id))
|
|
return InputScalarAsWidgetReplacement(frame_bb, id, label, data_type, v, format);
|
|
return InputScalarAsWidgetReplacement(frame_bb, id, label, data_type, v, format);
|
|
|
|
|
|
- // Actual slider behavior + render grab
|
|
|
|
ItemSize(total_bb, style.FramePadding.y);
|
|
ItemSize(total_bb, style.FramePadding.y);
|
|
- const bool value_changed = SliderBehavior(frame_bb, id, data_type, v, v_min, v_max, format, power);
|
|
|
|
|
|
+
|
|
|
|
+ // Draw frame
|
|
|
|
+ const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
|
|
|
+ RenderNavHighlight(frame_bb, id);
|
|
|
|
+ RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding);
|
|
|
|
+
|
|
|
|
+ // Slider behavior
|
|
|
|
+ ImRect grab_bb;
|
|
|
|
+ const bool value_changed = SliderBehavior(frame_bb, id, data_type, v, v_min, v_max, format, power, ImGuiSliderFlags_None, &grab_bb);
|
|
if (value_changed)
|
|
if (value_changed)
|
|
MarkItemValueChanged(id);
|
|
MarkItemValueChanged(id);
|
|
|
|
|
|
|
|
+ // Render grab
|
|
|
|
+ window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding);
|
|
|
|
+
|
|
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
|
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
|
char value_buf[64];
|
|
char value_buf[64];
|
|
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, v, format);
|
|
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, v, format);
|
|
@@ -9678,11 +9679,21 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
|
g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
|
|
g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
|
|
}
|
|
}
|
|
|
|
|
|
- // Actual slider behavior + render grab
|
|
|
|
- const bool value_changed = SliderBehavior(frame_bb, id, data_type, v, v_min, v_max, format, power, ImGuiSliderFlags_Vertical);
|
|
|
|
|
|
+
|
|
|
|
+ // Draw frame
|
|
|
|
+ const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
|
|
|
+ RenderNavHighlight(frame_bb, id);
|
|
|
|
+ RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding);
|
|
|
|
+
|
|
|
|
+ // Slider behavior
|
|
|
|
+ ImRect grab_bb;
|
|
|
|
+ const bool value_changed = SliderBehavior(frame_bb, id, data_type, v, v_min, v_max, format, power, ImGuiSliderFlags_Vertical, &grab_bb);
|
|
if (value_changed)
|
|
if (value_changed)
|
|
MarkItemValueChanged(id);
|
|
MarkItemValueChanged(id);
|
|
|
|
|
|
|
|
+ // Render grab
|
|
|
|
+ window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding);
|
|
|
|
+
|
|
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
|
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
|
// For the vertical slider we allow centered text to overlap the frame padding
|
|
// For the vertical slider we allow centered text to overlap the frame padding
|
|
char value_buf[64];
|
|
char value_buf[64];
|