IMGUI_API bool InputDoubleMinMax(const char* label, ImGuiDataType data_type, void* p_data, void* p_min, void* p_max, const void* p_step = NULL, const void* p_step_fast = NULL, const char* format = NULL, ImGuiInputTextFlags flags = 0);
// Note: p_data, p_step, p_step_fast are _pointers_ to a memory address holding the data. For an Input widget, p_step and p_step_fast are optional.
// Read code of e.g. InputFloat(), InputInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
bool ImGui::InputDoubleMinMax(const char* label, ImGuiDataType data_type, void* p_data, void* p_min, void* p_max, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return false;
ImGuiContext& g = *GImGui;
ImGuiStyle& style = g.Style;
if (format == NULL)
format = DataTypeGetInfo(data_type)->PrintFmt;
char buf[64];
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format);
// Testing ActiveId as a minor optimization as filtering is not needed until active
if (g.ActiveId == 0 && (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsScientific)) == 0)
flags |= InputScalar_DefaultCharsFilter(data_type, format);
flags |= ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string.
bool value_changed = false;
if (p_step == NULL)
{
if (InputText(label, buf, IM_ARRAYSIZE(buf), flags))
{
if (atof(buf) > *(const double*)p_max || atof(buf) < *(const double*)p_min)
{
value_changed = false;
}
else
{
value_changed = DataTypeApplyFromText(buf, data_type, p_data, format);
}
}
}
else
{
const float button_size = GetFrameHeight();
BeginGroup(); // The only purpose of the group here is to allow the caller to query item data e.g. IsItemActive()
PushID(label);
SetNextItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.ItemInnerSpacing.x) * 2));
if (InputText("", buf, IM_ARRAYSIZE(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view
{
if (atof(buf) > *(const double*)p_max || atof(buf) < *(const double*)p_min)
{
value_changed = false;
}
else
{
value_changed = DataTypeApplyFromText(buf, data_type, p_data, format);
}
}
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Inputable);
// Step buttons
const ImVec2 backup_frame_padding = style.FramePadding;
style.FramePadding.x = style.FramePadding.y;
ImGuiButtonFlags button_flags = ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups;
if (flags & ImGuiInputTextFlags_ReadOnly)
BeginDisabled();
SameLine(0, style.ItemInnerSpacing.x);
if (ButtonEx("-", ImVec2(button_size, button_size), button_flags))
{
if (*(const double*)p_data - *(const double*)(g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step) < *(const double*)p_min)
{
value_changed = false;
}
else
{
DataTypeApplyOp(data_type, '-', p_data, p_data, g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step);
value_changed = true;
}
}
SameLine(0, style.ItemInnerSpacing.x);
if (ButtonEx("+", ImVec2(button_size, button_size), button_flags))
{
if (*(const double*)p_data + *(const double*)(g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step) > *(const double*)p_max)
{
value_changed = false;
}
else
{
DataTypeApplyOp(data_type, '+', p_data, p_data, g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step);
value_changed = true;
}
}
if (flags & ImGuiInputTextFlags_ReadOnly)
EndDisabled();
const char* label_end = FindRenderedTextEnd(label);
if (label != label_end)
{
SameLine(0, style.ItemInnerSpacing.x);
TextEx(label, label_end);
}
style.FramePadding = backup_frame_padding;
PopID();
EndGroup();
}
if (value_changed)
MarkItemEdited(g.LastItemData.ID);
return value_changed;
}
实现ImGui带上下边界的微调输入框DoubleSpinBox
于 2024-02-22 11:22:49 首次发布
