DragScalar, InputScalar, SliderScalar: Added support for u8/s8/u16/s16 data types. We are reusing function instances for larger types to reduce code size. (#643, #320, #708, #1011)

This commit is contained in:
omar 2019-02-27 18:16:03 +01:00
parent 525a53a86b
commit 736d3e2654
4 changed files with 126 additions and 33 deletions

View File

@ -42,6 +42,8 @@ Breaking Changes:
Other Changes: Other Changes:
- Nav: Fixed a tap on AltGR (e.g. German keyboard) from navigation to the menu layer. - Nav: Fixed a tap on AltGR (e.g. German keyboard) from navigation to the menu layer.
- DragScalar, InputScalar, SliderScalar: Added support for u8/s8/u16/s16 data types.
We are reusing function instances for larger types to reduce code size. (#643, #320, #708, #1011)
- InputInt, InputFloat, InputScalar: Fix to keep the label of the +/- buttons centered when - InputInt, InputFloat, InputScalar: Fix to keep the label of the +/- buttons centered when
style.FramePadding.x is abnormally larger than style.FramePadding.y. Since the buttons are style.FramePadding.x is abnormally larger than style.FramePadding.y. Since the buttons are
meant to be square (to align with e.g. color button) we always use FramePadding.y. (#2367) meant to be square (to align with e.g. color button) we always use FramePadding.y. (#2367)

12
imgui.h
View File

@ -150,6 +150,10 @@ typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData *data);
typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data);
// Scalar data types // Scalar data types
typedef char ImS8; // 8-bit signed integer == char
typedef unsigned char ImU8; // 8-bit unsigned integer
typedef short ImS16; // 16-bit signed integer
typedef unsigned short ImU16; // 16-bit unsigned integer
typedef signed int ImS32; // 32-bit signed integer == int typedef signed int ImS32; // 32-bit signed integer == int
typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors) typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors)
#if defined(_MSC_VER) && !defined(__clang__) #if defined(_MSC_VER) && !defined(__clang__)
@ -884,10 +888,14 @@ enum ImGuiDragDropFlags_
// A primary data type // A primary data type
enum ImGuiDataType_ enum ImGuiDataType_
{ {
ImGuiDataType_S8, // char
ImGuiDataType_U8, // unsigned char
ImGuiDataType_S16, // short
ImGuiDataType_U16, // unsigned short
ImGuiDataType_S32, // int ImGuiDataType_S32, // int
ImGuiDataType_U32, // unsigned int ImGuiDataType_U32, // unsigned int
ImGuiDataType_S64, // long long, __int64 ImGuiDataType_S64, // long long / __int64
ImGuiDataType_U64, // unsigned long long, unsigned __int64 ImGuiDataType_U64, // unsigned long long / unsigned __int64
ImGuiDataType_Float, // float ImGuiDataType_Float, // float
ImGuiDataType_Double, // double ImGuiDataType_Double, // double
ImGuiDataType_COUNT ImGuiDataType_COUNT

View File

@ -1198,6 +1198,10 @@ static void ShowDemoWindowWidgets()
ImS64 LLONG_MAX = 9223372036854775807LL; ImS64 LLONG_MAX = 9223372036854775807LL;
ImU64 ULLONG_MAX = (2ULL * 9223372036854775807LL + 1); ImU64 ULLONG_MAX = (2ULL * 9223372036854775807LL + 1);
#endif #endif
const char s8_zero = 0, s8_one = 1, s8_fifty = 50, s8_min = -128, s8_max = 127;
const ImU8 u8_zero = 0, u8_one = 1, u8_fifty = 50, u8_min = 0, u8_max = 255;
const short s16_zero = 0, s16_one = 1, s16_fifty = 50, s16_min = -32768, s16_max = 32767;
const ImU16 u16_zero = 0, u16_one = 1, u16_fifty = 50, u16_min = 0, u16_max = 65535;
const ImS32 s32_zero = 0, s32_one = 1, s32_fifty = 50, s32_min = INT_MIN/2, s32_max = INT_MAX/2, s32_hi_a = INT_MAX/2 - 100, s32_hi_b = INT_MAX/2; const ImS32 s32_zero = 0, s32_one = 1, s32_fifty = 50, s32_min = INT_MIN/2, s32_max = INT_MAX/2, s32_hi_a = INT_MAX/2 - 100, s32_hi_b = INT_MAX/2;
const ImU32 u32_zero = 0, u32_one = 1, u32_fifty = 50, u32_min = 0, u32_max = UINT_MAX/2, u32_hi_a = UINT_MAX/2 - 100, u32_hi_b = UINT_MAX/2; const ImU32 u32_zero = 0, u32_one = 1, u32_fifty = 50, u32_min = 0, u32_max = UINT_MAX/2, u32_hi_a = UINT_MAX/2 - 100, u32_hi_b = UINT_MAX/2;
const ImS64 s64_zero = 0, s64_one = 1, s64_fifty = 50, s64_min = LLONG_MIN/2, s64_max = LLONG_MAX/2, s64_hi_a = LLONG_MAX/2 - 100, s64_hi_b = LLONG_MAX/2; const ImS64 s64_zero = 0, s64_one = 1, s64_fifty = 50, s64_min = LLONG_MIN/2, s64_max = LLONG_MAX/2, s64_hi_a = LLONG_MAX/2 - 100, s64_hi_b = LLONG_MAX/2;
@ -1206,6 +1210,10 @@ static void ShowDemoWindowWidgets()
const double f64_zero = 0., f64_one = 1., f64_lo_a = -1000000000000000.0, f64_hi_a = +1000000000000000.0; const double f64_zero = 0., f64_one = 1., f64_lo_a = -1000000000000000.0, f64_hi_a = +1000000000000000.0;
// State // State
static char s8_v = 127;
static ImU8 u8_v = 255;
static short s16_v = 32767;
static ImU16 u16_v = 65535;
static ImS32 s32_v = -1; static ImS32 s32_v = -1;
static ImU32 u32_v = (ImU32)-1; static ImU32 u32_v = (ImU32)-1;
static ImS64 s64_v = -1; static ImS64 s64_v = -1;
@ -1217,6 +1225,10 @@ static void ShowDemoWindowWidgets()
static bool drag_clamp = false; static bool drag_clamp = false;
ImGui::Text("Drags:"); ImGui::Text("Drags:");
ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp); ImGui::SameLine(); ShowHelpMarker("As with every widgets in dear imgui, we never modify values unless there is a user interaction.\nYou can override the clamping limits by using CTRL+Click to input a value."); ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp); ImGui::SameLine(); ShowHelpMarker("As with every widgets in dear imgui, we never modify values unless there is a user interaction.\nYou can override the clamping limits by using CTRL+Click to input a value.");
ImGui::DragScalar("drag s8", ImGuiDataType_S8, &s8_v, drag_speed, drag_clamp ? &s8_zero : NULL, drag_clamp ? &s8_fifty : NULL);
ImGui::DragScalar("drag u8", ImGuiDataType_U8, &u8_v, drag_speed, drag_clamp ? &u8_zero : NULL, drag_clamp ? &u8_fifty : NULL, "%u ms");
ImGui::DragScalar("drag s16", ImGuiDataType_S16, &s16_v, drag_speed, drag_clamp ? &s16_zero : NULL, drag_clamp ? &s16_fifty : NULL);
ImGui::DragScalar("drag u16", ImGuiDataType_U16, &u16_v, drag_speed, drag_clamp ? &u16_zero : NULL, drag_clamp ? &u16_fifty : NULL, "%u ms");
ImGui::DragScalar("drag s32", ImGuiDataType_S32, &s32_v, drag_speed, drag_clamp ? &s32_zero : NULL, drag_clamp ? &s32_fifty : NULL); ImGui::DragScalar("drag s32", ImGuiDataType_S32, &s32_v, drag_speed, drag_clamp ? &s32_zero : NULL, drag_clamp ? &s32_fifty : NULL);
ImGui::DragScalar("drag u32", ImGuiDataType_U32, &u32_v, drag_speed, drag_clamp ? &u32_zero : NULL, drag_clamp ? &u32_fifty : NULL, "%u ms"); ImGui::DragScalar("drag u32", ImGuiDataType_U32, &u32_v, drag_speed, drag_clamp ? &u32_zero : NULL, drag_clamp ? &u32_fifty : NULL, "%u ms");
ImGui::DragScalar("drag s64", ImGuiDataType_S64, &s64_v, drag_speed, drag_clamp ? &s64_zero : NULL, drag_clamp ? &s64_fifty : NULL); ImGui::DragScalar("drag s64", ImGuiDataType_S64, &s64_v, drag_speed, drag_clamp ? &s64_zero : NULL, drag_clamp ? &s64_fifty : NULL);
@ -1227,6 +1239,10 @@ static void ShowDemoWindowWidgets()
ImGui::DragScalar("drag double ^2", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", 2.0f); ImGui::DragScalar("drag double ^2", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", 2.0f);
ImGui::Text("Sliders"); ImGui::Text("Sliders");
ImGui::SliderScalar("slider s8 full", ImGuiDataType_S8, &s8_v, &s8_min, &s8_max, "%d");
ImGui::SliderScalar("slider u8 full", ImGuiDataType_U8, &u8_v, &u8_min, &u8_max, "%u");
ImGui::SliderScalar("slider s16 full", ImGuiDataType_S16, &s16_v, &s16_min, &s16_max, "%d");
ImGui::SliderScalar("slider u16 full", ImGuiDataType_U16, &u16_v, &u16_min, &u16_max, "%u");
ImGui::SliderScalar("slider s32 low", ImGuiDataType_S32, &s32_v, &s32_zero, &s32_fifty,"%d"); ImGui::SliderScalar("slider s32 low", ImGuiDataType_S32, &s32_v, &s32_zero, &s32_fifty,"%d");
ImGui::SliderScalar("slider s32 high", ImGuiDataType_S32, &s32_v, &s32_hi_a, &s32_hi_b, "%d"); ImGui::SliderScalar("slider s32 high", ImGuiDataType_S32, &s32_v, &s32_hi_a, &s32_hi_b, "%d");
ImGui::SliderScalar("slider s32 full", ImGuiDataType_S32, &s32_v, &s32_min, &s32_max, "%d"); ImGui::SliderScalar("slider s32 full", ImGuiDataType_S32, &s32_v, &s32_min, &s32_max, "%d");
@ -1249,6 +1265,10 @@ static void ShowDemoWindowWidgets()
static bool inputs_step = true; static bool inputs_step = true;
ImGui::Text("Inputs"); ImGui::Text("Inputs");
ImGui::Checkbox("Show step buttons", &inputs_step); ImGui::Checkbox("Show step buttons", &inputs_step);
ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d");
ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u");
ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d");
ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u");
ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d"); ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d");
ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%08X", ImGuiInputTextFlags_CharsHexadecimal); ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%08X", ImGuiInputTextFlags_CharsHexadecimal);
ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u"); ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u");

View File

@ -74,22 +74,30 @@ Index of this file:
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Those MIN/MAX values are not define because we need to point to them // Those MIN/MAX values are not define because we need to point to them
static const ImS32 IM_S32_MIN = INT_MIN; // (-2147483647 - 1), (0x80000000); static const char IM_S8_MIN = -128;
static const ImS32 IM_S32_MAX = INT_MAX; // (2147483647), (0x7FFFFFFF) static const char IM_S8_MAX = 127;
static const ImU32 IM_U32_MIN = 0; static const unsigned char IM_U8_MIN = 0;
static const ImU32 IM_U32_MAX = UINT_MAX; // (0xFFFFFFFF) static const unsigned char IM_U8_MAX = 0xFF;
static const short IM_S16_MIN = -32768;
static const short IM_S16_MAX = 32767;
static const unsigned short IM_U16_MIN = 0;
static const unsigned short IM_U16_MAX = 0xFFFF;
static const ImS32 IM_S32_MIN = INT_MIN; // (-2147483647 - 1), (0x80000000);
static const ImS32 IM_S32_MAX = INT_MAX; // (2147483647), (0x7FFFFFFF)
static const ImU32 IM_U32_MIN = 0;
static const ImU32 IM_U32_MAX = UINT_MAX; // (0xFFFFFFFF)
#ifdef LLONG_MIN #ifdef LLONG_MIN
static const ImS64 IM_S64_MIN = LLONG_MIN; // (-9223372036854775807ll - 1ll); static const ImS64 IM_S64_MIN = LLONG_MIN; // (-9223372036854775807ll - 1ll);
static const ImS64 IM_S64_MAX = LLONG_MAX; // (9223372036854775807ll); static const ImS64 IM_S64_MAX = LLONG_MAX; // (9223372036854775807ll);
#else #else
static const ImS64 IM_S64_MIN = -9223372036854775807LL - 1; static const ImS64 IM_S64_MIN = -9223372036854775807LL - 1;
static const ImS64 IM_S64_MAX = 9223372036854775807LL; static const ImS64 IM_S64_MAX = 9223372036854775807LL;
#endif #endif
static const ImU64 IM_U64_MIN = 0; static const ImU64 IM_U64_MIN = 0;
#ifdef ULLONG_MAX #ifdef ULLONG_MAX
static const ImU64 IM_U64_MAX = ULLONG_MAX; // (0xFFFFFFFFFFFFFFFFull); static const ImU64 IM_U64_MAX = ULLONG_MAX; // (0xFFFFFFFFFFFFFFFFull);
#else #else
static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1); static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1);
#endif #endif
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -1495,17 +1503,21 @@ struct ImGuiDataTypeInfo
static const ImGuiDataTypeInfo GDataTypeInfo[] = static const ImGuiDataTypeInfo GDataTypeInfo[] =
{ {
{ sizeof(int), "%d", "%d" }, { sizeof(char), "%d", "%d" }, // ImGuiDataType_S8
{ sizeof(unsigned int), "%u", "%u" }, { sizeof(unsigned char), "%u", "%u" },
{ sizeof(short), "%d", "%d" }, // ImGuiDataType_S16
{ sizeof(unsigned short), "%u", "%u" },
{ sizeof(int), "%d", "%d" }, // ImGuiDataType_S32
{ sizeof(unsigned int), "%u", "%u" },
#ifdef _MSC_VER #ifdef _MSC_VER
{ sizeof(ImS64), "%I64d","%I64d" }, { sizeof(ImS64), "%I64d","%I64d" }, // ImGuiDataType_S64
{ sizeof(ImU64), "%I64u","%I64u" }, { sizeof(ImU64), "%I64u","%I64u" },
#else #else
{ sizeof(ImS64), "%lld", "%lld" }, { sizeof(ImS64), "%lld", "%lld" }, // ImGuiDataType_S64
{ sizeof(ImU64), "%llu", "%llu" }, { sizeof(ImU64), "%llu", "%llu" },
#endif #endif
{ sizeof(float), "%f", "%f" }, // float are promoted to double in va_arg { sizeof(float), "%f", "%f" }, // ImGuiDataType_Float (float are promoted to double in va_arg)
{ sizeof(double), "%f", "%lf" }, { sizeof(double), "%f", "%lf" }, // ImGuiDataType_Double
}; };
IM_STATIC_ASSERT(IM_ARRAYSIZE(GDataTypeInfo) == ImGuiDataType_COUNT); IM_STATIC_ASSERT(IM_ARRAYSIZE(GDataTypeInfo) == ImGuiDataType_COUNT);
@ -1535,14 +1547,23 @@ static const char* PatchFormatStringFloatToInt(const char* fmt)
static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format) static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format)
{ {
if (data_type == ImGuiDataType_S32 || data_type == ImGuiDataType_U32) // Signedness doesn't matter when pushing the argument // Signedness doesn't matter when pushing integer arguments
if (data_type == ImGuiDataType_S32 || data_type == ImGuiDataType_U32)
return ImFormatString(buf, buf_size, format, *(const ImU32*)data_ptr); return ImFormatString(buf, buf_size, format, *(const ImU32*)data_ptr);
if (data_type == ImGuiDataType_S64 || data_type == ImGuiDataType_U64) // Signedness doesn't matter when pushing the argument if (data_type == ImGuiDataType_S64 || data_type == ImGuiDataType_U64)
return ImFormatString(buf, buf_size, format, *(const ImU64*)data_ptr); return ImFormatString(buf, buf_size, format, *(const ImU64*)data_ptr);
if (data_type == ImGuiDataType_Float) if (data_type == ImGuiDataType_Float)
return ImFormatString(buf, buf_size, format, *(const float*)data_ptr); return ImFormatString(buf, buf_size, format, *(const float*)data_ptr);
if (data_type == ImGuiDataType_Double) if (data_type == ImGuiDataType_Double)
return ImFormatString(buf, buf_size, format, *(const double*)data_ptr); return ImFormatString(buf, buf_size, format, *(const double*)data_ptr);
if (data_type == ImGuiDataType_S8)
return ImFormatString(buf, buf_size, format, *(const ImS8*)data_ptr);
if (data_type == ImGuiDataType_U8)
return ImFormatString(buf, buf_size, format, *(const ImU8*)data_ptr);
if (data_type == ImGuiDataType_S16)
return ImFormatString(buf, buf_size, format, *(const ImS16*)data_ptr);
if (data_type == ImGuiDataType_U16)
return ImFormatString(buf, buf_size, format, *(const ImU16*)data_ptr);
IM_ASSERT(0); IM_ASSERT(0);
return 0; return 0;
} }
@ -1553,13 +1574,29 @@ static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void*
IM_ASSERT(op == '+' || op == '-'); IM_ASSERT(op == '+' || op == '-');
switch (data_type) switch (data_type)
{ {
case ImGuiDataType_S8:
if (op == '+') *(ImS8*)output = *(const ImS8*)arg1 + *(const ImS8*)arg2;
else if (op == '-') *(ImS8*)output = *(const ImS8*)arg1 - *(const ImS8*)arg2;
return;
case ImGuiDataType_U8:
if (op == '+') *(ImU8*)output = *(const ImU8*)arg1 + *(const ImU8*)arg2;
else if (op == '-') *(ImU8*)output = *(const ImU8*)arg1 - *(const ImU8*)arg2;
return;
case ImGuiDataType_S16:
if (op == '+') *(ImS16*)output = *(const ImS16*)arg1 + *(const ImS16*)arg2;
else if (op == '-') *(ImS16*)output = *(const ImS16*)arg1 - *(const ImS16*)arg2;
return;
case ImGuiDataType_U16:
if (op == '+') *(ImU16*)output = *(const ImU16*)arg1 + *(const ImU16*)arg2;
else if (op == '-') *(ImU16*)output = *(const ImU16*)arg1 - *(const ImU16*)arg2;
return;
case ImGuiDataType_S32: case ImGuiDataType_S32:
if (op == '+') *(int*)output = *(const int*)arg1 + *(const int*)arg2; if (op == '+') *(ImS32*)output = *(const ImS32*)arg1 + *(const ImS32*)arg2;
else if (op == '-') *(int*)output = *(const int*)arg1 - *(const int*)arg2; else if (op == '-') *(ImS32*)output = *(const ImS32*)arg1 - *(const ImS32*)arg2;
return; return;
case ImGuiDataType_U32: case ImGuiDataType_U32:
if (op == '+') *(unsigned int*)output = *(const unsigned int*)arg1 + *(const ImU32*)arg2; if (op == '+') *(ImU32*)output = *(const ImU32*)arg1 + *(const ImU32*)arg2;
else if (op == '-') *(unsigned int*)output = *(const unsigned int*)arg1 - *(const ImU32*)arg2; else if (op == '-') *(ImU32*)output = *(const ImU32*)arg1 - *(const ImU32*)arg2;
return; return;
case ImGuiDataType_S64: case ImGuiDataType_S64:
if (op == '+') *(ImS64*)output = *(const ImS64*)arg1 + *(const ImS64*)arg2; if (op == '+') *(ImS64*)output = *(const ImS64*)arg1 + *(const ImS64*)arg2;
@ -1614,6 +1651,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
if (format == NULL) if (format == NULL)
format = GDataTypeInfo[data_type].ScanFmt; format = GDataTypeInfo[data_type].ScanFmt;
// FIXME-LEGACY: The aim is to remove those operators and write a proper expression evaluator at some point..
int arg1i = 0; int arg1i = 0;
if (data_type == ImGuiDataType_S32) if (data_type == ImGuiDataType_S32)
{ {
@ -1628,12 +1666,6 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
else if (op == '/') { if (sscanf(buf, "%f", &arg1f) && arg1f != 0.0f) *v = (int)(arg0i / arg1f); } // Divide else if (op == '/') { if (sscanf(buf, "%f", &arg1f) && arg1f != 0.0f) *v = (int)(arg0i / arg1f); } // Divide
else { if (sscanf(buf, format, &arg1i) == 1) *v = arg1i; } // Assign constant else { if (sscanf(buf, format, &arg1i) == 1) *v = arg1i; } // Assign constant
} }
else if (data_type == ImGuiDataType_U32 || data_type == ImGuiDataType_S64 || data_type == ImGuiDataType_U64)
{
// Assign constant
// FIXME: We don't bother handling support for legacy operators since they are a little too crappy. Instead we may implement a proper expression evaluator in the future.
sscanf(buf, format, data_ptr);
}
else if (data_type == ImGuiDataType_Float) else if (data_type == ImGuiDataType_Float)
{ {
// For floats we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in // For floats we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in
@ -1663,6 +1695,29 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide
else { *v = arg1f; } // Assign constant else { *v = arg1f; } // Assign constant
} }
else if (data_type == ImGuiDataType_U32 || data_type == ImGuiDataType_S64 || data_type == ImGuiDataType_U64)
{
// All other types assign constant
// We don't bother handling support for legacy operators since they are a little too crappy. Instead we will later implement a proper expression evaluator in the future.
sscanf(buf, format, data_ptr);
}
else
{
// Small types need a 32-bit buffer to receive the result from scanf()
int v32;
sscanf(buf, format, &v32);
if (data_type == ImGuiDataType_S8)
*(ImS8*)data_ptr = (ImS8)ImClamp(v32, (int)IM_S8_MIN, (int)IM_S8_MAX);
else if (data_type == ImGuiDataType_U8)
*(ImU8*)data_ptr = (ImU8)ImClamp(v32, (int)IM_U8_MIN, (int)IM_U8_MAX);
else if (data_type == ImGuiDataType_S16)
*(ImS16*)data_ptr = (ImS16)ImClamp(v32, (int)IM_S16_MIN, (int)IM_S16_MAX);
else if (data_type == ImGuiDataType_U16)
*(ImU16*)data_ptr = (ImU16)ImClamp(v32, (int)IM_U16_MIN, (int)IM_U16_MAX);
else
IM_ASSERT(0);
}
return memcmp(data_backup, data_ptr, GDataTypeInfo[data_type].Size) != 0; return memcmp(data_backup, data_ptr, GDataTypeInfo[data_type].Size) != 0;
} }
@ -1845,6 +1900,10 @@ bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* v, float v_s
switch (data_type) switch (data_type)
{ {
case ImGuiDataType_S8: { ImS32 v32 = (ImS32)*(ImS8*)v; bool r = DragBehaviorT<ImS32, ImS32, float >(ImGuiDataType_S32, &v32, v_speed, v_min ? *(const ImS8*) v_min : IM_S8_MIN, v_max ? *(const ImS8*)v_max : IM_S8_MAX, format, power, flags); if (r) *(ImS8*)v = (ImS8)v32; return r; }
case ImGuiDataType_U8: { ImU32 v32 = (ImU32)*(ImU8*)v; bool r = DragBehaviorT<ImU32, ImS32, float >(ImGuiDataType_U32, &v32, v_speed, v_min ? *(const ImU8*) v_min : IM_U8_MIN, v_max ? *(const ImU8*)v_max : IM_U8_MAX, format, power, flags); if (r) *(ImU8*)v = (ImU8)v32; return r; }
case ImGuiDataType_S16: { ImS32 v32 = (ImS32)*(ImS16*)v; bool r = DragBehaviorT<ImS32, ImS32, float >(ImGuiDataType_S32, &v32, v_speed, v_min ? *(const ImS16*)v_min : IM_S16_MIN, v_max ? *(const ImS16*)v_max : IM_S16_MAX, format, power, flags); if (r) *(ImS16*)v = (ImS16)v32; return r; }
case ImGuiDataType_U16: { ImU32 v32 = (ImU32)*(ImU16*)v; bool r = DragBehaviorT<ImU32, ImS32, float >(ImGuiDataType_U32, &v32, v_speed, v_min ? *(const ImU16*)v_min : IM_U16_MIN, v_max ? *(const ImU16*)v_max : IM_U16_MAX, format, power, flags); if (r) *(ImU16*)v = (ImU16)v32; return r; }
case ImGuiDataType_S32: return DragBehaviorT<ImS32, ImS32, float >(data_type, (ImS32*)v, v_speed, v_min ? *(const ImS32* )v_min : IM_S32_MIN, v_max ? *(const ImS32* )v_max : IM_S32_MAX, format, power, flags); case ImGuiDataType_S32: return DragBehaviorT<ImS32, ImS32, float >(data_type, (ImS32*)v, v_speed, v_min ? *(const ImS32* )v_min : IM_S32_MIN, v_max ? *(const ImS32* )v_max : IM_S32_MAX, format, power, flags);
case ImGuiDataType_U32: return DragBehaviorT<ImU32, ImS32, float >(data_type, (ImU32*)v, v_speed, v_min ? *(const ImU32* )v_min : IM_U32_MIN, v_max ? *(const ImU32* )v_max : IM_U32_MAX, format, power, flags); case ImGuiDataType_U32: return DragBehaviorT<ImU32, ImS32, float >(data_type, (ImU32*)v, v_speed, v_min ? *(const ImU32* )v_min : IM_U32_MIN, v_max ? *(const ImU32* )v_max : IM_U32_MAX, format, power, flags);
case ImGuiDataType_S64: return DragBehaviorT<ImS64, ImS64, double>(data_type, (ImS64*)v, v_speed, v_min ? *(const ImS64* )v_min : IM_S64_MIN, v_max ? *(const ImS64* )v_max : IM_S64_MAX, format, power, flags); case ImGuiDataType_S64: return DragBehaviorT<ImS64, ImS64, double>(data_type, (ImS64*)v, v_speed, v_min ? *(const ImS64* )v_min : IM_S64_MIN, v_max ? *(const ImS64* )v_max : IM_S64_MAX, format, power, flags);
@ -2269,6 +2328,10 @@ bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type
{ {
switch (data_type) switch (data_type)
{ {
case ImGuiDataType_S8: { ImS32 v32 = (ImS32)*(ImS8*)v; bool r = SliderBehaviorT<ImS32, ImS32, float >(bb, id, ImGuiDataType_S32, &v32, *(const ImS8*)v_min, *(const ImS8*)v_max, format, power, flags, out_grab_bb); if (r) *(ImS8*)v = (ImS8)v32; return r; }
case ImGuiDataType_U8: { ImU32 v32 = (ImU32)*(ImU8*)v; bool r = SliderBehaviorT<ImU32, ImS32, float >(bb, id, ImGuiDataType_U32, &v32, *(const ImU8*)v_min, *(const ImU8*)v_max, format, power, flags, out_grab_bb); if (r) *(ImU8*)v = (ImU8)v32; return r; }
case ImGuiDataType_S16: { ImS32 v32 = (ImS32)*(ImS16*)v; bool r = SliderBehaviorT<ImS32, ImS32, float >(bb, id, ImGuiDataType_S32, &v32, *(const ImS16*)v_min, *(const ImS16*)v_max, format, power, flags, out_grab_bb); if (r) *(ImS16*)v = (ImS16)v32; return r; }
case ImGuiDataType_U16: { ImU32 v32 = (ImU32)*(ImU16*)v; bool r = SliderBehaviorT<ImU32, ImS32, float >(bb, id, ImGuiDataType_U32, &v32, *(const ImU16*)v_min, *(const ImU16*)v_max, format, power, flags, out_grab_bb); if (r) *(ImU16*)v = (ImU16)v32; return r; }
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, out_grab_bb); 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);