Files
XCEngine/engine/src/UI/Widgets/UIScrollModel.cpp

68 lines
2.1 KiB
C++

#include <XCEngine/UI/Widgets/UIScrollModel.h>
#include <algorithm>
#include <cmath>
namespace XCEngine {
namespace UI {
namespace Widgets {
float ComputeUIScrollOverflow(float contentExtent, float viewportExtent) {
return (std::max)(0.0f, contentExtent - viewportExtent);
}
float ClampUIScrollOffset(float offset, float contentExtent, float viewportExtent) {
return (std::max)(0.0f, (std::min)(offset, ComputeUIScrollOverflow(contentExtent, viewportExtent)));
}
UIScrollWheelResult ApplyUIScrollWheel(
float offset,
float wheelDelta,
float contentExtent,
float viewportExtent,
float wheelStep,
float epsilon) {
UIScrollWheelResult result = {};
result.offsetBefore = ClampUIScrollOffset(offset, contentExtent, viewportExtent);
result.overflow = ComputeUIScrollOverflow(contentExtent, viewportExtent);
result.offsetAfter = result.offsetBefore;
if (result.overflow <= 0.0f || std::fabs(wheelDelta) <= epsilon || wheelStep <= 0.0f) {
return result;
}
const float scrollUnits = wheelDelta / 120.0f;
result.offsetAfter = ClampUIScrollOffset(
result.offsetBefore - scrollUnits * wheelStep,
contentExtent,
viewportExtent);
result.changed = std::fabs(result.offsetAfter - result.offsetBefore) > epsilon;
return result;
}
float EnsureUIScrollOffsetVisible(
float offset,
float itemStart,
float itemExtent,
float contentExtent,
float viewportExtent) {
const float clampedOffset = ClampUIScrollOffset(offset, contentExtent, viewportExtent);
if (viewportExtent <= 0.0f || itemExtent <= 0.0f) {
return clampedOffset;
}
const float itemEnd = itemStart + itemExtent;
const float viewportEnd = clampedOffset + viewportExtent;
float nextOffset = clampedOffset;
if (itemStart < clampedOffset) {
nextOffset = itemStart;
} else if (itemEnd > viewportEnd) {
nextOffset = itemEnd - viewportExtent;
}
return ClampUIScrollOffset(nextOffset, contentExtent, viewportExtent);
}
} // namespace Widgets
} // namespace UI
} // namespace XCEngine