Fixed multiple issues in ScrollableContainer and added a new containerVerticalSnap property.

This commit is contained in:
Leon Styhre 2022-09-16 18:49:39 +02:00
parent 79a661b744
commit dca3a6d232
2 changed files with 30 additions and 36 deletions

View file

@ -18,12 +18,14 @@ ScrollableContainer::ScrollableContainer()
: mRenderer {Renderer::getInstance()} : mRenderer {Renderer::getInstance()}
, mScrollPos {0.0f, 0.0f} , mScrollPos {0.0f, 0.0f}
, mScrollDir {0.0f, 0.0f} , mScrollDir {0.0f, 0.0f}
, mAdjustedHeight {0.0f}
, mClipSpacing {0.0f} , mClipSpacing {0.0f}
, mAutoScrollDelay {0} , mAutoScrollDelay {0}
, mAutoScrollSpeed {0} , mAutoScrollSpeed {0}
, mAutoScrollAccumulator {0} , mAutoScrollAccumulator {0}
, mAutoScrollResetAccumulator {0} , mAutoScrollResetAccumulator {0}
, mAdjustedAutoScrollSpeed {0} , mAdjustedAutoScrollSpeed {0}
, mVerticalSnap {true}
, mUpdatedSize {false} , mUpdatedSize {false}
{ {
// Set the modifier to get equivalent scrolling speed regardless of screen resolution. // Set the modifier to get equivalent scrolling speed regardless of screen resolution.
@ -64,18 +66,6 @@ void ScrollableContainer::reset()
mAutoScrollResetAccumulator = 0; mAutoScrollResetAccumulator = 0;
mAutoScrollAccumulator = -mAutoScrollDelay + mAutoScrollSpeed; mAutoScrollAccumulator = -mAutoScrollDelay + mAutoScrollSpeed;
mAtEnd = false; mAtEnd = false;
// This is needed to resize to the font height boundary when we keep running in the background
// while launching games.
if (!mChildren.empty()) {
float combinedHeight {
mChildren.front()->getFont()->getHeight(mChildren.front()->getLineSpacing())};
if (mChildren.front()->getSize().y > mSize.y) {
float numLines {mSize.y / combinedHeight};
mSize.y = floorf(numLines) * combinedHeight;
if (mSize.y == 0.0f)
mSize.y = combinedHeight;
}
}
} }
void ScrollableContainer::applyTheme(const std::shared_ptr<ThemeData>& theme, void ScrollableContainer::applyTheme(const std::shared_ptr<ThemeData>& theme,
@ -90,6 +80,9 @@ void ScrollableContainer::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (!elem || !elem->has("container")) if (!elem || !elem->has("container"))
return; return;
if (elem->has("containerVerticalSnap"))
mVerticalSnap = elem->get<bool>("containerVerticalSnap");
if (elem->has("containerScrollSpeed")) { if (elem->has("containerScrollSpeed")) {
mAutoScrollSpeedConstant = mAutoScrollSpeedConstant =
AUTO_SCROLL_SPEED / glm::clamp(elem->get<float>("containerScrollSpeed"), 0.1f, 10.0f); AUTO_SCROLL_SPEED / glm::clamp(elem->get<float>("containerScrollSpeed"), 0.1f, 10.0f);
@ -111,14 +104,6 @@ void ScrollableContainer::update(int deltaTime)
if (!isVisible() || mSize == glm::vec2 {0.0f, 0.0f}) if (!isVisible() || mSize == glm::vec2 {0.0f, 0.0f})
return; return;
// Don't scroll if the media viewer or screensaver is active or if text scrolling is disabled;
if (mWindow->isMediaViewerActive() || mWindow->isScreensaverActive() ||
!mWindow->getAllowTextScrolling()) {
if (mScrollPos != glm::vec2 {} && !mWindow->isLaunchScreenDisplayed())
reset();
return;
}
const glm::vec2 contentSize {mChildren.front()->getSize()}; const glm::vec2 contentSize {mChildren.front()->getSize()};
float rowModifier {1.0f}; float rowModifier {1.0f};
@ -133,16 +118,23 @@ void ScrollableContainer::update(int deltaTime)
} }
// Resize container to font height boundary to avoid rendering a fraction of the last line. // Resize container to font height boundary to avoid rendering a fraction of the last line.
if (!mUpdatedSize && contentSize.y > mSize.y) { if (!mUpdatedSize) {
float numLines {mSize.y / combinedHeight}; if (mVerticalSnap) {
mSize.y = floorf(numLines) * combinedHeight; float numLines {std::floor(mSize.y / combinedHeight)};
mAdjustedHeight = std::round(numLines * combinedHeight);
}
else {
mAdjustedHeight = mSize.y;
}
mUpdatedSize = true; mUpdatedSize = true;
} }
else if (mUpdatedSize) {
// If there are less than 8 lines of text, accelerate the scrolling further. // Don't scroll if the media viewer or screensaver is active or if text scrolling is disabled;
float lines {mSize.y / combinedHeight}; if (mWindow->isMediaViewerActive() || mWindow->isScreensaverActive() ||
if (lines < 8.0f) !mWindow->getAllowTextScrolling()) {
rowModifier = lines / 8.0f; if (mScrollPos != glm::vec2 {} && !mWindow->isLaunchScreenDisplayed())
reset();
return;
} }
if (!mAdjustedAutoScrollSpeed) { if (!mAdjustedAutoScrollSpeed) {
@ -164,7 +156,7 @@ void ScrollableContainer::update(int deltaTime)
mAutoScrollAccumulator += deltaTime; mAutoScrollAccumulator += deltaTime;
while (mAutoScrollAccumulator >= while (mAutoScrollAccumulator >=
static_cast<int>(rowModifier * static_cast<float>(mAdjustedAutoScrollSpeed))) { static_cast<int>(rowModifier * static_cast<float>(mAdjustedAutoScrollSpeed))) {
if (contentSize.y > mSize.y) if (contentSize.y > mAdjustedHeight)
mScrollPos += mScrollDir; mScrollPos += mScrollDir;
mAutoScrollAccumulator -= mAutoScrollAccumulator -=
static_cast<int>(rowModifier * static_cast<float>(mAdjustedAutoScrollSpeed)); static_cast<int>(rowModifier * static_cast<float>(mAdjustedAutoScrollSpeed));
@ -177,16 +169,16 @@ void ScrollableContainer::update(int deltaTime)
if (mScrollPos.y < 0.0f) if (mScrollPos.y < 0.0f)
mScrollPos.y = 0.0f; mScrollPos.y = 0.0f;
if (mScrollPos.x + getSize().x > contentSize.x) { if (mScrollPos.x + mSize.x > contentSize.x) {
mScrollPos.x = contentSize.x - getSize().x; mScrollPos.x = contentSize.x - mSize.x;
mAtEnd = true; mAtEnd = true;
} }
if (contentSize.y < getSize().y) { if (contentSize.y < mAdjustedHeight) {
mScrollPos.y = 0.0f; mScrollPos.y = 0.0f;
} }
else if (mScrollPos.y + getSize().y > contentSize.y) { else if (mScrollPos.y + mAdjustedHeight > contentSize.y) {
mScrollPos.y = contentSize.y - getSize().y; mScrollPos.y = contentSize.y - mAdjustedHeight;
mAtEnd = true; mAtEnd = true;
} }
@ -224,7 +216,7 @@ void ScrollableContainer::render(const glm::mat4& parentTrans)
glm::vec3 dimScaled {}; glm::vec3 dimScaled {};
dimScaled.x = std::fabs(trans[3].x + mSize.x); dimScaled.x = std::fabs(trans[3].x + mSize.x);
dimScaled.y = std::fabs(trans[3].y + mSize.y); dimScaled.y = std::fabs(trans[3].y + mAdjustedHeight);
glm::ivec2 clipDim {static_cast<int>(ceilf(dimScaled.x - trans[3].x)), glm::ivec2 clipDim {static_cast<int>(ceilf(dimScaled.x - trans[3].x)),
static_cast<int>(ceilf(dimScaled.y - trans[3].y))}; static_cast<int>(ceilf(dimScaled.y - trans[3].y))};
@ -240,7 +232,7 @@ void ScrollableContainer::render(const glm::mat4& parentTrans)
mRenderer->setMatrix(trans); mRenderer->setMatrix(trans);
if (Settings::getInstance()->getBool("DebugText")) if (Settings::getInstance()->getBool("DebugText"))
mRenderer->drawRect(0.0f, mScrollPos.y, mSize.x, mSize.y, 0x0000FF33, 0x0000FF33); mRenderer->drawRect(0.0f, mScrollPos.y, mSize.x, mAdjustedHeight, 0x0000FF33, 0x0000FF33);
GuiComponent::renderChildren(trans); GuiComponent::renderChildren(trans);
mRenderer->popClipRect(); mRenderer->popClipRect();

View file

@ -49,6 +49,7 @@ private:
glm::vec2 mScrollPos; glm::vec2 mScrollPos;
glm::vec2 mScrollDir; glm::vec2 mScrollDir;
float mAdjustedHeight;
float mAutoScrollResetDelayConstant; float mAutoScrollResetDelayConstant;
float mAutoScrollDelayConstant; float mAutoScrollDelayConstant;
float mAutoScrollSpeedConstant; float mAutoScrollSpeedConstant;
@ -61,6 +62,7 @@ private:
int mAutoScrollResetAccumulator; int mAutoScrollResetAccumulator;
int mAdjustedAutoScrollSpeed; int mAdjustedAutoScrollSpeed;
bool mVerticalSnap;
bool mAtEnd; bool mAtEnd;
bool mUpdatedSize; bool mUpdatedSize;
}; };