mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-02-11 08:49:50 +00:00
Fix: crash when window can't be placed on low resolution screens. (#10932)
Co-authored-by: Jonathan G Rennison <j.g.rennison@gmail.com>
This commit is contained in:
parent
c43a23cea8
commit
0f3dd9c796
@ -83,6 +83,32 @@ static inline T Clamp(const T a, const T min, const T max)
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamp a value between an interval.
|
||||||
|
*
|
||||||
|
* This function returns a value which is between the given interval of
|
||||||
|
* min and max. If the given value is in this interval the value itself
|
||||||
|
* is returned otherwise the border of the interval is returned, according
|
||||||
|
* which side of the interval was 'left'.
|
||||||
|
*
|
||||||
|
* @note If the min value is greater than the max, return value is the average of the min and max.
|
||||||
|
* @param a The value to clamp/truncate.
|
||||||
|
* @param min The minimum of the interval.
|
||||||
|
* @param max the maximum of the interval.
|
||||||
|
* @returns A value between min and max which is closest to a.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
static inline T SoftClamp(const T a, const T min, const T max)
|
||||||
|
{
|
||||||
|
if (min > max) {
|
||||||
|
using U = std::make_unsigned_t<T>;
|
||||||
|
return min - (U(min) - max) / 2;
|
||||||
|
}
|
||||||
|
if (a <= min) return min;
|
||||||
|
if (a >= max) return max;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clamp an integer between an interval.
|
* Clamp an integer between an interval.
|
||||||
*
|
*
|
||||||
|
@ -1140,8 +1140,8 @@ struct QueryWindow : public Window {
|
|||||||
void FindWindowPlacementAndResize(int def_width, int def_height) override
|
void FindWindowPlacementAndResize(int def_width, int def_height) override
|
||||||
{
|
{
|
||||||
/* Position query window over the calling window, ensuring it's within screen bounds. */
|
/* Position query window over the calling window, ensuring it's within screen bounds. */
|
||||||
this->left = Clamp(parent->left + (parent->width / 2) - (this->width / 2), 0, _screen.width - this->width);
|
this->left = SoftClamp(parent->left + (parent->width / 2) - (this->width / 2), 0, _screen.width - this->width);
|
||||||
this->top = Clamp(parent->top + (parent->height / 2) - (this->height / 2), 0, _screen.height - this->height);
|
this->top = SoftClamp(parent->top + (parent->height / 2) - (this->height / 2), 0, _screen.height - this->height);
|
||||||
this->SetDirty();
|
this->SetDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,3 +120,13 @@ TEST_CASE("ClampTo")
|
|||||||
/* max uint64_t gets clamped to max int64_t. */
|
/* max uint64_t gets clamped to max int64_t. */
|
||||||
CHECK(std::numeric_limits<int64_t>::max() == ClampTo<int64_t>(std::numeric_limits<uint64_t>::max()));
|
CHECK(std::numeric_limits<int64_t>::max() == ClampTo<int64_t>(std::numeric_limits<uint64_t>::max()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("SoftClamp")
|
||||||
|
{
|
||||||
|
/* Special behaviour of soft clamp returning the average of min/max when min is higher than max. */
|
||||||
|
CHECK(1250 == SoftClamp(0, 1500, 1000));
|
||||||
|
int million = 1000 * 1000;
|
||||||
|
CHECK(1250 * million == SoftClamp(0, 1500 * million, 1000 * million));
|
||||||
|
CHECK(0 == SoftClamp(0, 1500 * million, -1500 * million));
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user