engine: sync editor rendering and ui changes
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <XCEngine/UI/Layout/LayoutEngine.h>
|
||||
#include <XCEngine/UI/Layout/UITabStripLayout.h>
|
||||
#include <XCEngine/UI/Style/DocumentStyleCompiler.h>
|
||||
#include <XCEngine/UI/Widgets/UIScrollModel.h>
|
||||
#include <XCEngine/UI/Widgets/UITabStripModel.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -985,14 +986,6 @@ std::string BuildNodeStateKeySegment(
|
||||
return ToStdString(source.tagName) + "#" + std::to_string(siblingIndex);
|
||||
}
|
||||
|
||||
float ComputeScrollOverflow(float contentExtent, float viewportExtent) {
|
||||
return (std::max)(0.0f, contentExtent - viewportExtent);
|
||||
}
|
||||
|
||||
float ClampScrollOffset(float offset, float contentExtent, float viewportExtent) {
|
||||
return (std::max)(0.0f, (std::min)(offset, ComputeScrollOverflow(contentExtent, viewportExtent)));
|
||||
}
|
||||
|
||||
bool RectContainsPoint(const UIRect& rect, const UIPoint& point) {
|
||||
return point.x >= rect.x &&
|
||||
point.x <= rect.x + rect.width &&
|
||||
@@ -1885,7 +1878,7 @@ void ArrangeNode(
|
||||
const auto found = verticalScrollOffsets.find(node.stateKey);
|
||||
const float requestedOffset = found != verticalScrollOffsets.end() ? found->second : 0.0f;
|
||||
node.scrollViewportRect = contentRect;
|
||||
node.scrollOffsetY = ClampScrollOffset(
|
||||
node.scrollOffsetY = Widgets::ClampUIScrollOffset(
|
||||
requestedOffset,
|
||||
node.contentDesiredSize.height,
|
||||
contentRect.height);
|
||||
@@ -1932,7 +1925,7 @@ RuntimeLayoutNode* FindDeepestScrollTarget(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (ComputeScrollOverflow(node.contentDesiredSize.height, node.scrollViewportRect.height) <= 0.0f) {
|
||||
if (Widgets::ComputeUIScrollOverflow(node.contentDesiredSize.height, node.scrollViewportRect.height) <= 0.0f) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -2001,7 +1994,7 @@ bool ApplyScrollWheelEvent(
|
||||
|
||||
scrollDebugSnapshot.lastTargetStateKey = hoveredScrollView->stateKey;
|
||||
scrollDebugSnapshot.lastViewportRect = hoveredScrollView->scrollViewportRect;
|
||||
scrollDebugSnapshot.lastOverflow = ComputeScrollOverflow(
|
||||
scrollDebugSnapshot.lastOverflow = Widgets::ComputeUIScrollOverflow(
|
||||
hoveredScrollView->contentDesiredSize.height,
|
||||
hoveredScrollView->scrollViewportRect.height);
|
||||
|
||||
@@ -2022,18 +2015,18 @@ bool ApplyScrollWheelEvent(
|
||||
: target->scrollOffsetY;
|
||||
scrollDebugSnapshot.lastOffsetBefore = oldOffset;
|
||||
|
||||
const float scrollUnits = event.wheelDelta / 120.0f;
|
||||
const float nextOffset = ClampScrollOffset(
|
||||
oldOffset - scrollUnits * 48.0f,
|
||||
const Widgets::UIScrollWheelResult scrollResult = Widgets::ApplyUIScrollWheel(
|
||||
oldOffset,
|
||||
event.wheelDelta,
|
||||
target->contentDesiredSize.height,
|
||||
target->scrollViewportRect.height);
|
||||
scrollDebugSnapshot.lastOffsetAfter = nextOffset;
|
||||
if (std::fabs(nextOffset - oldOffset) <= 0.01f) {
|
||||
scrollDebugSnapshot.lastOffsetAfter = scrollResult.offsetAfter;
|
||||
if (!scrollResult.changed) {
|
||||
scrollDebugSnapshot.lastResult = "Scroll delta clamped to current offset";
|
||||
return false;
|
||||
}
|
||||
|
||||
verticalScrollOffsets[target->stateKey] = nextOffset;
|
||||
verticalScrollOffsets[target->stateKey] = scrollResult.offsetAfter;
|
||||
++scrollDebugSnapshot.handledWheelEventCount;
|
||||
scrollDebugSnapshot.lastResult = "Handled";
|
||||
return true;
|
||||
@@ -2545,7 +2538,8 @@ void SyncScrollOffsets(
|
||||
const RuntimeLayoutNode& node,
|
||||
std::unordered_map<std::string, float>& verticalScrollOffsets) {
|
||||
if (node.isScrollView) {
|
||||
const float overflow = ComputeScrollOverflow(node.contentDesiredSize.height, node.scrollViewportRect.height);
|
||||
const float overflow =
|
||||
Widgets::ComputeUIScrollOverflow(node.contentDesiredSize.height, node.scrollViewportRect.height);
|
||||
if (overflow <= 0.0f || node.scrollOffsetY <= 0.0f) {
|
||||
verticalScrollOffsets.erase(node.stateKey);
|
||||
} else {
|
||||
@@ -3009,7 +3003,7 @@ UIScreenFrameResult UIDocumentScreenHost::BuildFrame(
|
||||
if (const RuntimeLayoutNode* primaryScrollView = FindFirstScrollView(root); primaryScrollView != nullptr) {
|
||||
m_scrollDebugSnapshot.primaryTargetStateKey = primaryScrollView->stateKey;
|
||||
m_scrollDebugSnapshot.primaryViewportRect = primaryScrollView->scrollViewportRect;
|
||||
m_scrollDebugSnapshot.primaryOverflow = ComputeScrollOverflow(
|
||||
m_scrollDebugSnapshot.primaryOverflow = Widgets::ComputeUIScrollOverflow(
|
||||
primaryScrollView->contentDesiredSize.height,
|
||||
primaryScrollView->scrollViewportRect.height);
|
||||
} else {
|
||||
|
||||
67
engine/src/UI/Widgets/UIScrollModel.cpp
Normal file
67
engine/src/UI/Widgets/UIScrollModel.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user