mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 05:01:05 +01:00 
			
		
		
		
	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:
		
							
								
								
									
										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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user