Internals: Data types: Added s64, u64 data types. Added support in InputScalar(). Removed internal.h InputScalarEx() to InputScalar(). Removed cheap-relative-operators support in recently added U32 data path, since this is heading toward being legacy code. + Fixed InputDouble parsing code. (#1011, #320, #708)
This commit is contained in:
parent
d9fa1f869e
commit
4780ac1ca4
120
imgui.cpp
120
imgui.cpp
@ -8459,8 +8459,10 @@ void ImGui::BulletText(const char* fmt, ...)
|
||||
|
||||
static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format)
|
||||
{
|
||||
if (data_type == ImGuiDataType_Int32 || data_type == ImGuiDataType_Uint32)
|
||||
return ImFormatString(buf, buf_size, format, *(const int*)data_ptr);
|
||||
if (data_type == ImGuiDataType_S32 || data_type == ImGuiDataType_U32) // Signedness doesn't matter when pushing the argument
|
||||
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
|
||||
return ImFormatString(buf, buf_size, format, *(const ImU64*)data_ptr);
|
||||
if (data_type == ImGuiDataType_Float)
|
||||
return ImFormatString(buf, buf_size, format, *(const float*)data_ptr);
|
||||
if (data_type == ImGuiDataType_Double)
|
||||
@ -8472,34 +8474,56 @@ static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType da
|
||||
static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg1, const void* arg2)
|
||||
{
|
||||
IM_ASSERT(op == '+' || op == '-');
|
||||
if (data_type == ImGuiDataType_Int32)
|
||||
switch (data_type)
|
||||
{
|
||||
if (op == '+') *(int*)output = *(const int*)arg1 + *(const int*)arg2;
|
||||
else if (op == '-') *(int*)output = *(const int*)arg1 - *(const int*)arg2;
|
||||
}
|
||||
else if (data_type == ImGuiDataType_Uint32)
|
||||
{
|
||||
if (op == '+') *(unsigned int*)output = *(const unsigned int*)arg1 + *(const unsigned int*)arg2;
|
||||
else if (op == '-') *(unsigned int*)output = *(const unsigned int*)arg1 - *(const unsigned int*)arg2;
|
||||
}
|
||||
else if (data_type == ImGuiDataType_Float)
|
||||
{
|
||||
if (op == '+') *(float*)output = *(const float*)arg1 + *(const float*)arg2;
|
||||
else if (op == '-') *(float*)output = *(const float*)arg1 - *(const float*)arg2;
|
||||
}
|
||||
else if (data_type == ImGuiDataType_Double)
|
||||
{
|
||||
if (op == '+') *(double*)output = *(const double*)arg1 + *(const double*)arg2;
|
||||
else if (op == '-') *(double*)output = *(const double*)arg1 - *(const double*)arg2;
|
||||
case ImGuiDataType_S32:
|
||||
if (op == '+') *(int*)output = *(const int*)arg1 + *(const int*)arg2;
|
||||
else if (op == '-') *(int*)output = *(const int*)arg1 - *(const int*)arg2;
|
||||
return;
|
||||
case ImGuiDataType_U32:
|
||||
if (op == '+') *(unsigned int*)output = *(const unsigned int*)arg1 + *(const ImU32*)arg2;
|
||||
else if (op == '-') *(unsigned int*)output = *(const unsigned int*)arg1 - *(const ImU32*)arg2;
|
||||
return;
|
||||
case ImGuiDataType_S64:
|
||||
if (op == '+') *(ImS64*)output = *(const ImS64*)arg1 + *(const ImS64*)arg2;
|
||||
else if (op == '-') *(ImS64*)output = *(const ImS64*)arg1 - *(const ImS64*)arg2;
|
||||
return;
|
||||
case ImGuiDataType_U64:
|
||||
if (op == '+') *(ImU64*)output = *(const ImU64*)arg1 + *(const ImU64*)arg2;
|
||||
else if (op == '-') *(ImU64*)output = *(const ImU64*)arg1 - *(const ImU64*)arg2;
|
||||
return;
|
||||
case ImGuiDataType_Float:
|
||||
if (op == '+') *(float*)output = *(const float*)arg1 + *(const float*)arg2;
|
||||
else if (op == '-') *(float*)output = *(const float*)arg1 - *(const float*)arg2;
|
||||
return;
|
||||
case ImGuiDataType_Double:
|
||||
if (op == '+') *(double*)output = *(const double*)arg1 + *(const double*)arg2;
|
||||
else if (op == '-') *(double*)output = *(const double*)arg1 - *(const double*)arg2;
|
||||
return;
|
||||
case ImGuiDataType_COUNT: break;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t GDataTypeSize[ImGuiDataType_COUNT] =
|
||||
struct ImGuiDataTypeInfo
|
||||
{
|
||||
sizeof(int),
|
||||
sizeof(unsigned int),
|
||||
sizeof(float),
|
||||
sizeof(double)
|
||||
size_t Size;
|
||||
const char* PrintFmt; // Unused
|
||||
const char* ScanFmt;
|
||||
};
|
||||
|
||||
static const ImGuiDataTypeInfo GDataTypeInfo[ImGuiDataType_COUNT] =
|
||||
{
|
||||
{ sizeof(int), "%d", "%d" },
|
||||
{ sizeof(unsigned int), "%u", "%u" },
|
||||
#ifdef _MSC_VER
|
||||
{ sizeof(ImS64), "%I64d","%I64d" },
|
||||
{ sizeof(ImU64), "%I64u","%I64u" },
|
||||
#else
|
||||
{ sizeof(ImS64), "%lld", "%lld" },
|
||||
{ sizeof(ImU64), "%llu", "%llu" },
|
||||
#endif
|
||||
{ sizeof(float), "%f", "%f" }, // float are promoted to double in va_arg
|
||||
{ sizeof(double), "%f", "%lf" },
|
||||
};
|
||||
|
||||
// User can input math operators (e.g. +100) to edit a numerical values.
|
||||
@ -8525,47 +8549,41 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
|
||||
if (!buf[0])
|
||||
return false;
|
||||
|
||||
// Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all.
|
||||
IM_ASSERT(data_type < ImGuiDataType_COUNT);
|
||||
int data_backup[2];
|
||||
IM_ASSERT(GDataTypeSize[data_type] <= sizeof(data_backup));
|
||||
memcpy(data_backup, data_ptr, GDataTypeSize[data_type]);
|
||||
IM_ASSERT(GDataTypeInfo[data_type].Size <= sizeof(data_backup));
|
||||
memcpy(data_backup, data_ptr, GDataTypeInfo[data_type].Size);
|
||||
|
||||
if (scalar_format == NULL)
|
||||
scalar_format = GDataTypeInfo[data_type].ScanFmt;
|
||||
|
||||
int arg1i = 0;
|
||||
float arg1f = 0.0f;
|
||||
if (data_type == ImGuiDataType_Int32)
|
||||
if (data_type == ImGuiDataType_S32)
|
||||
{
|
||||
if (!scalar_format)
|
||||
scalar_format = "%d";
|
||||
int* v = (int*)data_ptr;
|
||||
int arg0i = *v;
|
||||
float arg1f = 0.0f;
|
||||
if (op && sscanf(initial_value_buf, scalar_format, &arg0i) < 1)
|
||||
return false;
|
||||
// Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision
|
||||
if (op == '+') { if (sscanf(buf, "%d", &arg1i)) *v = (int)(arg0i + arg1i); } // Add (use "+-" to subtract)
|
||||
else if (op == '*') { if (sscanf(buf, "%f", &arg1f)) *v = (int)(arg0i * arg1f); } // Multiply
|
||||
else if (op == '/') { if (sscanf(buf, "%f", &arg1f) && arg1f != 0.0f) *v = (int)(arg0i / arg1f); } // Divide
|
||||
else { if (sscanf(buf, scalar_format, &arg0i) == 1) *v = arg0i; } // Assign integer constant
|
||||
else { if (sscanf(buf, scalar_format, &arg1i) == 1) *v = arg1i; } // Assign constant
|
||||
}
|
||||
else if (data_type == ImGuiDataType_Uint32)
|
||||
else if (data_type == ImGuiDataType_U32 || data_type == ImGuiDataType_S64 || data_type == ImGuiDataType_U64)
|
||||
{
|
||||
if (!scalar_format)
|
||||
scalar_format = "%u";
|
||||
ImU32* v = (unsigned int*)data_ptr;
|
||||
ImU32 arg0i = *v;
|
||||
if (op && sscanf(initial_value_buf, scalar_format, &arg0i) < 1)
|
||||
return false;
|
||||
// Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision
|
||||
if (op == '+') { if (sscanf(buf, "%d", &arg1i)) *v = (ImU32)(arg0i + arg1f); } // Add (use "+-" to subtract)
|
||||
else if (op == '*') { if (sscanf(buf, "%f", &arg1f)) *v = (ImU32)(arg0i * arg1f); } // Multiply
|
||||
else if (op == '/') { if (sscanf(buf, "%f", &arg1f) && arg1f != 0.0f) *v = (ImU32)(arg0i / arg1f); }// Divide
|
||||
else { if (sscanf(buf, scalar_format, &arg0i) == 1) *v = arg0i; } // Assign integer constant
|
||||
// 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, scalar_format, data_ptr);
|
||||
}
|
||||
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
|
||||
scalar_format = "%f";
|
||||
float* v = (float*)data_ptr;
|
||||
float arg0f = *v;
|
||||
float arg0f = *v, arg1f = 0.0f;
|
||||
if (op && sscanf(initial_value_buf, scalar_format, &arg0f) < 1)
|
||||
return false;
|
||||
if (sscanf(buf, scalar_format, &arg1f) < 1)
|
||||
@ -8579,7 +8597,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
|
||||
{
|
||||
scalar_format = "%lf"; // scanf differentiate float/double unlike printf which forces everything to double because of ellipsis
|
||||
double* v = (double*)data_ptr;
|
||||
double arg0f = *v;
|
||||
double arg0f = *v, arg1f = 0.0;
|
||||
if (op && sscanf(initial_value_buf, scalar_format, &arg0f) < 1)
|
||||
return false;
|
||||
if (sscanf(buf, scalar_format, &arg1f) < 1)
|
||||
@ -8589,7 +8607,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
|
||||
else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide
|
||||
else { *v = arg1f; } // Assign constant
|
||||
}
|
||||
return memcmp(data_backup, data_ptr, GDataTypeSize[data_type]) != 0;
|
||||
return memcmp(data_backup, data_ptr, GDataTypeInfo[data_type].Size) != 0;
|
||||
}
|
||||
|
||||
// Create text input in place of a slider (when CTRL+Clicking on slider)
|
||||
@ -10589,7 +10607,7 @@ bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, co
|
||||
}
|
||||
|
||||
// NB: scalar_format here must be a simple "%xx" format string with no prefix/suffix (unlike the Drag/Slider functions "format" argument)
|
||||
bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags)
|
||||
bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@ -10648,20 +10666,20 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data
|
||||
bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, const char* format, ImGuiInputTextFlags extra_flags)
|
||||
{
|
||||
extra_flags |= ImGuiInputTextFlags_CharsScientific;
|
||||
return InputScalarEx(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), format, extra_flags);
|
||||
return InputScalar(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), format, extra_flags);
|
||||
}
|
||||
|
||||
bool ImGui::InputDouble(const char* label, double* v, double step, double step_fast, const char* format, ImGuiInputTextFlags extra_flags)
|
||||
{
|
||||
extra_flags |= ImGuiInputTextFlags_CharsScientific;
|
||||
return InputScalarEx(label, ImGuiDataType_Double, (void*)v, (void*)(step>0.0 ? &step : NULL), (void*)(step_fast>0.0 ? &step_fast : NULL), format, extra_flags);
|
||||
return InputScalar(label, ImGuiDataType_Double, (void*)v, (void*)(step>0.0 ? &step : NULL), (void*)(step_fast>0.0 ? &step_fast : NULL), format, extra_flags);
|
||||
}
|
||||
|
||||
bool ImGui::InputInt(const char* label, int* v, int step, int step_fast, ImGuiInputTextFlags extra_flags)
|
||||
{
|
||||
// Hexadecimal input provided as a convenience but the flag name is awkward. Typically you'd use InputText() to parse your own data, if you want to handle prefixes.
|
||||
const char* format = (extra_flags & ImGuiInputTextFlags_CharsHexadecimal) ? "%08X" : "%d";
|
||||
return InputScalarEx(label, ImGuiDataType_Int32, (void*)v, (void*)(step>0 ? &step : NULL), (void*)(step_fast>0 ? &step_fast : NULL), format, extra_flags);
|
||||
return InputScalar(label, ImGuiDataType_S32, (void*)v, (void*)(step>0 ? &step : NULL), (void*)(step_fast>0 ? &step_fast : NULL), format, extra_flags);
|
||||
}
|
||||
|
||||
bool ImGui::InputFloatN(const char* label, float* v, int components, const char* format, ImGuiInputTextFlags extra_flags)
|
||||
|
14
imgui.h
14
imgui.h
@ -72,13 +72,11 @@ struct ImGuiSizeCallbackData; // Structure used to constraint window size
|
||||
struct ImGuiListClipper; // Helper to manually clip large list of items
|
||||
struct ImGuiPayload; // User data payload for drag and drop operations
|
||||
struct ImGuiContext; // ImGui context (opaque)
|
||||
|
||||
#ifndef ImTextureID
|
||||
typedef void* ImTextureID; // User data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp)
|
||||
#endif
|
||||
|
||||
// Typedefs and Enumerations (declared as int for compatibility with old C++ and to not pollute the top of this file)
|
||||
typedef unsigned int ImU32; // 32-bit unsigned integer (typically used to store packed colors)
|
||||
typedef unsigned int ImGuiID; // Unique ID used by widgets (typically hashed from a stack of string)
|
||||
typedef unsigned short ImWchar; // Character for keyboard input/display
|
||||
typedef int ImGuiCol; // enum: a color identifier for styling // enum ImGuiCol_
|
||||
@ -105,12 +103,19 @@ typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(),CollapsingHeader()
|
||||
typedef int ImGuiWindowFlags; // flags: for Begin*() // enum ImGuiWindowFlags_
|
||||
typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data);
|
||||
typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data);
|
||||
|
||||
// Scalar data types
|
||||
typedef signed int ImS32; // 32-bit signed integer == int
|
||||
typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors)
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
typedef unsigned __int64 ImU64; // 64-bit unsigned integer
|
||||
typedef signed __int64 ImS64; // 64-bit signed integer
|
||||
typedef unsigned __int64 ImU64; // 64-bit unsigned integer
|
||||
#else
|
||||
typedef unsigned long long ImU64; // 64-bit unsigned integer
|
||||
typedef signed long long ImS64; // 64-bit signed integer
|
||||
typedef unsigned long long ImU64; // 64-bit unsigned integer
|
||||
#endif
|
||||
|
||||
// 2d vector
|
||||
struct ImVec2
|
||||
{
|
||||
float x, y;
|
||||
@ -122,6 +127,7 @@ struct ImVec2
|
||||
#endif
|
||||
};
|
||||
|
||||
// 4d vector (often used to store floating-point colors)
|
||||
struct ImVec4
|
||||
{
|
||||
float x, y, z, w;
|
||||
|
@ -345,8 +345,8 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
static float f0 = 0.001f;
|
||||
ImGui::InputFloat("input float", &f0, 0.01f, 1.0f);
|
||||
|
||||
static double d0 = 999999.000001;
|
||||
ImGui::InputDouble("input double", &d0, 0.01f, 1.0f, "%.6f");
|
||||
static double d0 = 999999.00000001;
|
||||
ImGui::InputDouble("input double", &d0, 0.01f, 1.0f, "%.8f");
|
||||
|
||||
static float f1 = 1.e10f;
|
||||
ImGui::InputFloat("input scientific", &f1, 0.0f, 0.0f, "%e");
|
||||
|
@ -248,8 +248,10 @@ enum ImGuiPlotType
|
||||
|
||||
enum ImGuiDataType
|
||||
{
|
||||
ImGuiDataType_Int32,
|
||||
ImGuiDataType_Uint32,
|
||||
ImGuiDataType_S32, // int
|
||||
ImGuiDataType_U32, // unsigned int
|
||||
ImGuiDataType_S64, // long long / __int64
|
||||
ImGuiDataType_U64, // unsigned long long / unsigned __int64
|
||||
ImGuiDataType_Float,
|
||||
ImGuiDataType_Double,
|
||||
ImGuiDataType_COUNT
|
||||
@ -1110,7 +1112,7 @@ namespace ImGui
|
||||
IMGUI_API bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);
|
||||
IMGUI_API bool InputFloatN(const char* label, float* v, int components, const char* format, ImGuiInputTextFlags extra_flags);
|
||||
IMGUI_API bool InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags);
|
||||
IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* format, ImGuiInputTextFlags extra_flags = 0);
|
||||
IMGUI_API bool InputScalar(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* format, ImGuiInputTextFlags extra_flags = 0);
|
||||
IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format);
|
||||
|
||||
IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags);
|
||||
|
Loading…
Reference in New Issue
Block a user