#include #include #include 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