User can input math operators (e.g. +100) to edit a numerical values. NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess..
| 2089 | // User can input math operators (e.g. +100) to edit a numerical values. |
| 2090 | // NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess.. |
| 2091 | bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format) |
| 2092 | { |
| 2093 | while (ImCharIsBlankA(*buf)) |
| 2094 | buf++; |
| 2095 | if (!buf[0]) |
| 2096 | return false; |
| 2097 | |
| 2098 | // Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all. |
| 2099 | const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type); |
| 2100 | ImGuiDataTypeTempStorage data_backup; |
| 2101 | memcpy(&data_backup, p_data, type_info->Size); |
| 2102 | |
| 2103 | // Sanitize format |
| 2104 | // - For float/double we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in, so force them into %f and %lf |
| 2105 | // - In theory could treat empty format as using default, but this would only cover rare/bizarre case of using InputScalar() + integer + format string without %. |
| 2106 | char format_sanitized[32]; |
| 2107 | if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) |
| 2108 | format = type_info->ScanFmt; |
| 2109 | else |
| 2110 | format = ImParseFormatSanitizeForScanning(format, format_sanitized, IM_ARRAYSIZE(format_sanitized)); |
| 2111 | |
| 2112 | // Small types need a 32-bit buffer to receive the result from scanf() |
| 2113 | int v32 = 0; |
| 2114 | if (sscanf(buf, format, type_info->Size >= 4 ? p_data : &v32) < 1) |
| 2115 | return false; |
| 2116 | if (type_info->Size < 4) |
| 2117 | { |
| 2118 | if (data_type == ImGuiDataType_S8) |
| 2119 | *(ImS8*)p_data = (ImS8)ImClamp(v32, (int)IM_S8_MIN, (int)IM_S8_MAX); |
| 2120 | else if (data_type == ImGuiDataType_U8) |
| 2121 | *(ImU8*)p_data = (ImU8)ImClamp(v32, (int)IM_U8_MIN, (int)IM_U8_MAX); |
| 2122 | else if (data_type == ImGuiDataType_S16) |
| 2123 | *(ImS16*)p_data = (ImS16)ImClamp(v32, (int)IM_S16_MIN, (int)IM_S16_MAX); |
| 2124 | else if (data_type == ImGuiDataType_U16) |
| 2125 | *(ImU16*)p_data = (ImU16)ImClamp(v32, (int)IM_U16_MIN, (int)IM_U16_MAX); |
| 2126 | else |
| 2127 | IM_ASSERT(0); |
| 2128 | } |
| 2129 | |
| 2130 | return memcmp(&data_backup, p_data, type_info->Size) != 0; |
| 2131 | } |
| 2132 | |
| 2133 | template<typename T> |
| 2134 | static int DataTypeCompareT(const T* lhs, const T* rhs) |
nothing calls this directly
no test coverage detected