InputInt, InputScalar: +/- buttons now respects the natural type limits instead of overflowing or underflowing the value.

This commit is contained in:
omar 2019-02-27 18:59:17 +01:00
parent 736d3e2654
commit f02705fbaa
3 changed files with 26 additions and 22 deletions

View File

@ -47,6 +47,8 @@ Other Changes:
- 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)
- InputInt, InputScalar: +/- buttons now respects the natural type limits instead of
overflowing or underflowing the value.
- InputText: Fixed an edge case crash that would happen if another widget sharing the same ID - InputText: Fixed an edge case crash that would happen if another widget sharing the same ID
is being swapped with an InputText that has yet to be activated. is being swapped with an InputText that has yet to be activated.
- InputText: Fixed various display corruption related to swapping the underlying buffer while - InputText: Fixed various display corruption related to swapping the underlying buffer while

View File

@ -225,12 +225,15 @@ static inline double ImAtof(const char* s)
static inline float ImFloorStd(float x) { return floorf(x); } // we already uses our own ImFloor() { return (float)(int)v } internally so the standard one wrapper is named differently (it's used by stb_truetype) static inline float ImFloorStd(float x) { return floorf(x); } // we already uses our own ImFloor() { return (float)(int)v } internally so the standard one wrapper is named differently (it's used by stb_truetype)
static inline float ImCeil(float x) { return ceilf(x); } static inline float ImCeil(float x) { return ceilf(x); }
#endif #endif
// - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support for variety of types: signed/unsigned int/long long float/double, using templates here but we could also redefine them 6 times // - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support for variety of types: signed/unsigned int/long long float/double
// (Exceptionally using templates here but we could also redefine them for variety of types)
template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; } template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; } template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); } template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); }
template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; } template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
template<typename T> static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; }
template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; }
// - Misc maths helpers // - Misc maths helpers
static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); } static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); }
static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); } static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); }

View File

@ -1568,51 +1568,50 @@ static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType da
return 0; return 0;
} }
// FIXME: Adding support for clamping on boundaries of the data type would be nice.
static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg1, const void* arg2) static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg1, const void* arg2)
{ {
IM_ASSERT(op == '+' || op == '-'); IM_ASSERT(op == '+' || op == '-');
switch (data_type) switch (data_type)
{ {
case ImGuiDataType_S8: case ImGuiDataType_S8:
if (op == '+') *(ImS8*)output = *(const ImS8*)arg1 + *(const ImS8*)arg2; if (op == '+') { *(ImS8*)output = ImAddClampOverflow(*(const ImS8*)arg1, *(const ImS8*)arg2, IM_S8_MIN, IM_S8_MAX); }
else if (op == '-') *(ImS8*)output = *(const ImS8*)arg1 - *(const ImS8*)arg2; if (op == '-') { *(ImS8*)output = ImSubClampOverflow(*(const ImS8*)arg1, *(const ImS8*)arg2, IM_S8_MIN, IM_S8_MAX); }
return; return;
case ImGuiDataType_U8: case ImGuiDataType_U8:
if (op == '+') *(ImU8*)output = *(const ImU8*)arg1 + *(const ImU8*)arg2; if (op == '+') { *(ImU8*)output = ImAddClampOverflow(*(const ImU8*)arg1, *(const ImU8*)arg2, IM_U8_MIN, IM_U8_MAX); }
else if (op == '-') *(ImU8*)output = *(const ImU8*)arg1 - *(const ImU8*)arg2; if (op == '-') { *(ImU8*)output = ImSubClampOverflow(*(const ImU8*)arg1, *(const ImU8*)arg2, IM_U8_MIN, IM_U8_MAX); }
return; return;
case ImGuiDataType_S16: case ImGuiDataType_S16:
if (op == '+') *(ImS16*)output = *(const ImS16*)arg1 + *(const ImS16*)arg2; if (op == '+') { *(ImS16*)output = ImAddClampOverflow(*(const ImS16*)arg1, *(const ImS16*)arg2, IM_S16_MIN, IM_S16_MAX); }
else if (op == '-') *(ImS16*)output = *(const ImS16*)arg1 - *(const ImS16*)arg2; if (op == '-') { *(ImS16*)output = ImSubClampOverflow(*(const ImS16*)arg1, *(const ImS16*)arg2, IM_S16_MIN, IM_S16_MAX); }
return; return;
case ImGuiDataType_U16: case ImGuiDataType_U16:
if (op == '+') *(ImU16*)output = *(const ImU16*)arg1 + *(const ImU16*)arg2; if (op == '+') { *(ImU16*)output = ImAddClampOverflow(*(const ImU16*)arg1, *(const ImU16*)arg2, IM_U16_MIN, IM_U16_MAX); }
else if (op == '-') *(ImU16*)output = *(const ImU16*)arg1 - *(const ImU16*)arg2; if (op == '-') { *(ImU16*)output = ImSubClampOverflow(*(const ImU16*)arg1, *(const ImU16*)arg2, IM_U16_MIN, IM_U16_MAX); }
return; return;
case ImGuiDataType_S32: case ImGuiDataType_S32:
if (op == '+') *(ImS32*)output = *(const ImS32*)arg1 + *(const ImS32*)arg2; if (op == '+') { *(ImS32*)output = ImAddClampOverflow(*(const ImS32*)arg1, *(const ImS32*)arg2, IM_S32_MIN, IM_S32_MAX); }
else if (op == '-') *(ImS32*)output = *(const ImS32*)arg1 - *(const ImS32*)arg2; if (op == '-') { *(ImS32*)output = ImSubClampOverflow(*(const ImS32*)arg1, *(const ImS32*)arg2, IM_S32_MIN, IM_S32_MAX); }
return; return;
case ImGuiDataType_U32: case ImGuiDataType_U32:
if (op == '+') *(ImU32*)output = *(const ImU32*)arg1 + *(const ImU32*)arg2; if (op == '+') { *(ImU32*)output = ImAddClampOverflow(*(const ImU32*)arg1, *(const ImU32*)arg2, IM_U32_MIN, IM_U32_MAX); }
else if (op == '-') *(ImU32*)output = *(const ImU32*)arg1 - *(const ImU32*)arg2; if (op == '-') { *(ImU32*)output = ImSubClampOverflow(*(const ImU32*)arg1, *(const ImU32*)arg2, IM_U32_MIN, IM_U32_MAX); }
return; return;
case ImGuiDataType_S64: case ImGuiDataType_S64:
if (op == '+') *(ImS64*)output = *(const ImS64*)arg1 + *(const ImS64*)arg2; if (op == '+') { *(ImS64*)output = ImAddClampOverflow(*(const ImS64*)arg1, *(const ImS64*)arg2, IM_S64_MIN, IM_S64_MAX); }
else if (op == '-') *(ImS64*)output = *(const ImS64*)arg1 - *(const ImS64*)arg2; if (op == '-') { *(ImS64*)output = ImSubClampOverflow(*(const ImS64*)arg1, *(const ImS64*)arg2, IM_S64_MIN, IM_S64_MAX); }
return; return;
case ImGuiDataType_U64: case ImGuiDataType_U64:
if (op == '+') *(ImU64*)output = *(const ImU64*)arg1 + *(const ImU64*)arg2; if (op == '+') { *(ImU64*)output = ImAddClampOverflow(*(const ImU64*)arg1, *(const ImU64*)arg2, IM_U64_MIN, IM_U64_MAX); }
else if (op == '-') *(ImU64*)output = *(const ImU64*)arg1 - *(const ImU64*)arg2; if (op == '-') { *(ImU64*)output = ImSubClampOverflow(*(const ImU64*)arg1, *(const ImU64*)arg2, IM_U64_MIN, IM_U64_MAX); }
return; return;
case ImGuiDataType_Float: case ImGuiDataType_Float:
if (op == '+') *(float*)output = *(const float*)arg1 + *(const float*)arg2; if (op == '+') { *(float*)output = *(const float*)arg1 + *(const float*)arg2; }
else if (op == '-') *(float*)output = *(const float*)arg1 - *(const float*)arg2; if (op == '-') { *(float*)output = *(const float*)arg1 - *(const float*)arg2; }
return; return;
case ImGuiDataType_Double: case ImGuiDataType_Double:
if (op == '+') *(double*)output = *(const double*)arg1 + *(const double*)arg2; if (op == '+') { *(double*)output = *(const double*)arg1 + *(const double*)arg2; }
else if (op == '-') *(double*)output = *(const double*)arg1 - *(const double*)arg2; if (op == '-') { *(double*)output = *(const double*)arg1 - *(const double*)arg2; }
return; return;
case ImGuiDataType_COUNT: break; case ImGuiDataType_COUNT: break;
} }