mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-03-06 14:27:43 +00:00
Added a number of properties to allow horizontally scrolling text entries with CarouselComponent
Also added support for rotating horizontal scrollable containers
This commit is contained in:
parent
950541b261
commit
6ae8c87864
|
@ -92,6 +92,7 @@ void GamelistView::onShow()
|
|||
|
||||
updateView(CursorState::CURSOR_STOPPED);
|
||||
mPrimary->finishAnimation(0);
|
||||
mPrimary->onShowPrimary();
|
||||
}
|
||||
|
||||
void GamelistView::onTransition()
|
||||
|
|
|
@ -46,6 +46,7 @@ void SystemView::onShow()
|
|||
stopViewVideos();
|
||||
mFadeOpacity = 0.0f;
|
||||
mTransitionAnim = false;
|
||||
mPrimary->onShowPrimary();
|
||||
}
|
||||
|
||||
void SystemView::onTransition()
|
||||
|
|
|
@ -145,10 +145,14 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"colorEnd", COLOR},
|
||||
{"gradientType", STRING},
|
||||
{"text", STRING},
|
||||
{"textRelativeScale", FLOAT},
|
||||
{"textColor", COLOR},
|
||||
{"textBackgroundColor", COLOR},
|
||||
{"textSelectedColor", COLOR},
|
||||
{"textSelectedBackgroundColor", COLOR},
|
||||
{"textHorizontalScrolling", BOOLEAN},
|
||||
{"textHorizontalScrollSpeed", FLOAT},
|
||||
{"textHorizontalScrollDelay", FLOAT},
|
||||
{"fontPath", PATH},
|
||||
{"fontSize", FLOAT},
|
||||
{"letterCase", STRING},
|
||||
|
|
|
@ -30,6 +30,7 @@ TextComponent::TextComponent()
|
|||
, mHorizontalAlignment {ALIGN_LEFT}
|
||||
, mVerticalAlignment {ALIGN_CENTER}
|
||||
, mLineSpacing {1.5f}
|
||||
, mRelativeScale {1.0f}
|
||||
, mNoTopMargin {false}
|
||||
, mSelectable {false}
|
||||
, mVerticalAutoSizing {false}
|
||||
|
@ -37,6 +38,7 @@ TextComponent::TextComponent()
|
|||
, mScrollSpeed {0.0f}
|
||||
, mScrollSpeedMultiplier {1.0f}
|
||||
, mScrollDelay {1500.0f}
|
||||
, mScrollGap {1.5f}
|
||||
, mScrollOffset1 {0.0f}
|
||||
, mScrollOffset2 {0.0f}
|
||||
, mScrollTime {0.0f}
|
||||
|
@ -50,7 +52,13 @@ TextComponent::TextComponent(const std::string& text,
|
|||
Alignment verticalAlignment,
|
||||
glm::vec3 pos,
|
||||
glm::vec2 size,
|
||||
unsigned int bgcolor)
|
||||
unsigned int bgcolor,
|
||||
float lineSpacing,
|
||||
float relativeScale,
|
||||
bool horizontalScrolling,
|
||||
float scrollSpeedMultiplier,
|
||||
float scrollDelay,
|
||||
float scrollGap)
|
||||
: mFont {nullptr}
|
||||
, mRenderer {Renderer::getInstance()}
|
||||
, mColor {0x000000FF}
|
||||
|
@ -66,14 +74,16 @@ TextComponent::TextComponent(const std::string& text,
|
|||
, mAutoCalcExtent {1, 1}
|
||||
, mHorizontalAlignment {horizontalAlignment}
|
||||
, mVerticalAlignment {verticalAlignment}
|
||||
, mLineSpacing {1.5f}
|
||||
, mLineSpacing {lineSpacing}
|
||||
, mRelativeScale {relativeScale}
|
||||
, mNoTopMargin {false}
|
||||
, mSelectable {false}
|
||||
, mVerticalAutoSizing {false}
|
||||
, mHorizontalScrolling {false}
|
||||
, mHorizontalScrolling {horizontalScrolling}
|
||||
, mScrollSpeed {0.0f}
|
||||
, mScrollSpeedMultiplier {1.0f}
|
||||
, mScrollDelay {1500.0f}
|
||||
, mScrollSpeedMultiplier {scrollSpeedMultiplier}
|
||||
, mScrollDelay {scrollDelay}
|
||||
, mScrollGap {scrollGap}
|
||||
, mScrollOffset1 {0.0f}
|
||||
, mScrollOffset2 {0.0f}
|
||||
, mScrollTime {0.0f}
|
||||
|
@ -81,6 +91,7 @@ TextComponent::TextComponent(const std::string& text,
|
|||
setFont(font);
|
||||
setColor(color);
|
||||
setBackgroundColor(bgcolor);
|
||||
setHorizontalScrolling(mHorizontalScrolling);
|
||||
setText(text, false);
|
||||
setPosition(pos);
|
||||
setSize(size);
|
||||
|
@ -185,7 +196,8 @@ void TextComponent::setCapitalize(bool capitalize)
|
|||
|
||||
void TextComponent::render(const glm::mat4& parentTrans)
|
||||
{
|
||||
if (!isVisible() || mThemeOpacity == 0.0f || mSize.x == 0.0f || mSize.y == 0.0f)
|
||||
if (!isVisible() || mTextCache == nullptr || mThemeOpacity == 0.0f || mSize.x == 0.0f ||
|
||||
mSize.y == 0.0f)
|
||||
return;
|
||||
|
||||
glm::mat4 trans {parentTrans * getTransform()};
|
||||
|
@ -198,34 +210,31 @@ void TextComponent::render(const glm::mat4& parentTrans)
|
|||
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0x0000FF33, 0x0000FF33);
|
||||
}
|
||||
|
||||
if (mHorizontalScrolling && mTextCache != nullptr) {
|
||||
// Clip everything to be inside our bounds.
|
||||
glm::vec3 dim {mSize.x, mSize.y, 0.0f};
|
||||
dim.x = (trans[0].x * dim.x + trans[3].x) - trans[3].x;
|
||||
dim.y = (trans[1].y * dim.y + trans[3].y) - trans[3].y;
|
||||
|
||||
const int clipRectPosX {static_cast<int>(std::round(trans[3].x))};
|
||||
const int clipRectPosY {static_cast<int>(std::round(trans[3].y))};
|
||||
const int clipRectSizeX {static_cast<int>(std::round(dim.x))};
|
||||
const int clipRectSizeY {static_cast<int>(std::round(dim.y) + 1.0f)};
|
||||
|
||||
mRenderer->pushClipRect(glm::ivec2 {clipRectPosX, clipRectPosY},
|
||||
glm::ivec2 {clipRectSizeX, clipRectSizeY});
|
||||
|
||||
float offsetX {0.0f};
|
||||
float offsetX {0.0f};
|
||||
|
||||
if (mHorizontalScrolling) {
|
||||
if (mTextCache->metrics.size.x < mSize.x) {
|
||||
// This is needed for text that does not fill the entire width and thus gets aligned.
|
||||
if (mHorizontalAlignment == Alignment::ALIGN_CENTER)
|
||||
offsetX = (mSize.x - mTextCache->metrics.size.x) / 2.0f;
|
||||
offsetX = ((mSize.x * mRelativeScale) - mTextCache->metrics.size.x) / 2.0f;
|
||||
else if (mHorizontalAlignment == Alignment::ALIGN_RIGHT)
|
||||
offsetX = mSize.x - mTextCache->metrics.size.x;
|
||||
offsetX = (mSize.x * mRelativeScale) - mTextCache->metrics.size.x;
|
||||
}
|
||||
|
||||
if (offsetX < 0.0f)
|
||||
offsetX = 0.0f;
|
||||
|
||||
// Clip the texture using a fragment shader which allows for rotation and other benefits
|
||||
// as compared to using the pushClipRect() function.
|
||||
mTextCache->setClipRegion(glm::vec4 {mScrollOffset1, 0.0f,
|
||||
(mSize.x * mRelativeScale) + mScrollOffset1,
|
||||
mTextCache->metrics.size.y});
|
||||
|
||||
trans = glm::translate(trans, glm::vec3 {offsetX - mScrollOffset1, 0.0f, 0.0f});
|
||||
}
|
||||
|
||||
auto renderFunc = [this](glm::mat4 trans) {
|
||||
if (mRenderBackground)
|
||||
auto renderFunc = [this](glm::mat4 trans, bool secondPass) {
|
||||
if (mRenderBackground && !secondPass)
|
||||
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, mBgColor, mBgColor, false,
|
||||
mOpacity * mThemeOpacity, mDimming);
|
||||
if (mTextCache) {
|
||||
|
@ -259,50 +268,73 @@ void TextComponent::render(const glm::mat4& parentTrans)
|
|||
trans = glm::translate(trans, glm::vec3 {0.0f, yOff, 0.0f});
|
||||
mRenderer->setMatrix(trans);
|
||||
|
||||
// Draw the text area, where the text is actually located.
|
||||
if (Settings::getInstance()->getBool("DebugText")) {
|
||||
switch (mHorizontalAlignment) {
|
||||
case ALIGN_LEFT: {
|
||||
mRenderer->drawRect(0.0f, 0.0f, mTextCache->metrics.size.x,
|
||||
mTextCache->metrics.size.y, 0x00000033, 0x00000033);
|
||||
break;
|
||||
}
|
||||
case ALIGN_CENTER: {
|
||||
mRenderer->drawRect(mHorizontalScrolling ?
|
||||
0.0f :
|
||||
(mSize.x - mTextCache->metrics.size.x) / 2.0f,
|
||||
0.0f, mTextCache->metrics.size.x,
|
||||
mTextCache->metrics.size.y, 0x00000033, 0x00000033);
|
||||
break;
|
||||
}
|
||||
case ALIGN_RIGHT: {
|
||||
const float relativeScaleOffset {(mSize.x - (mSize.x * mRelativeScale)) / 2.0f};
|
||||
if (mHorizontalScrolling && !secondPass) {
|
||||
if (mScrollOffset1 <= mTextCache->metrics.size.x) {
|
||||
const float width {mTextCache->metrics.size.x - mScrollOffset1};
|
||||
mRenderer->drawRect(
|
||||
mHorizontalScrolling ? 0.0f : mSize.x - mTextCache->metrics.size.x,
|
||||
0.0f, mTextCache->metrics.size.x, mTextCache->metrics.size.y,
|
||||
0x00000033, 0x00000033);
|
||||
break;
|
||||
mScrollOffset1 + relativeScaleOffset, 0.0f,
|
||||
width > mSize.x * mRelativeScale ? mSize.x * mRelativeScale : width,
|
||||
mTextCache->metrics.size.y, 0x00000033, 0x00000033);
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
else if (mHorizontalScrolling && secondPass) {
|
||||
if ((mSize.x * mRelativeScale) - -mScrollOffset2 > 0.0f) {
|
||||
mRenderer->drawRect(relativeScaleOffset, 0.0f,
|
||||
(mSize.x * mRelativeScale) - -mScrollOffset2,
|
||||
mTextCache->metrics.size.y, 0x00000033, 0x00000033);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (mHorizontalAlignment) {
|
||||
case ALIGN_LEFT: {
|
||||
mRenderer->drawRect(0.0f, 0.0f, mTextCache->metrics.size.x,
|
||||
mTextCache->metrics.size.y, 0x00000033, 0x00000033);
|
||||
break;
|
||||
}
|
||||
case ALIGN_CENTER: {
|
||||
mRenderer->drawRect((mSize.x - mTextCache->metrics.size.x) / 2.0f, 0.0f,
|
||||
mTextCache->metrics.size.x,
|
||||
mTextCache->metrics.size.y, 0x00000033, 0x00000033);
|
||||
break;
|
||||
}
|
||||
case ALIGN_RIGHT: {
|
||||
mRenderer->drawRect(mSize.x - mTextCache->metrics.size.x, 0.0f,
|
||||
mTextCache->metrics.size.x,
|
||||
mTextCache->metrics.size.y, 0x00000033, 0x00000033);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// We need to adjust positioning if the relative scale multiplier is in use.
|
||||
if (mRelativeScale < 1.0f) {
|
||||
trans = glm::translate(
|
||||
trans, glm::vec3 {(mSize.x - (mSize.x * mRelativeScale)) / 2.0f, 0.0f, 0.0f});
|
||||
mRenderer->setMatrix(trans);
|
||||
}
|
||||
|
||||
mFont->renderTextCache(mTextCache.get());
|
||||
}
|
||||
};
|
||||
|
||||
renderFunc(trans);
|
||||
renderFunc(trans, false);
|
||||
|
||||
if (mHorizontalScrolling && mTextCache != nullptr && mTextCache->metrics.size.x > mSize.x) {
|
||||
// Render again if the text has moved far enough to repeat.
|
||||
if (mHorizontalScrolling && mTextCache->metrics.size.x > mSize.x * mRelativeScale) {
|
||||
if (mScrollOffset2 < 0.0f) {
|
||||
mTextCache->setClipRegion(glm::vec4 {mScrollOffset2, 0.0f,
|
||||
(mSize.x * mRelativeScale) + mScrollOffset2,
|
||||
mTextCache->metrics.size.y});
|
||||
trans = glm::translate(parentTrans * getTransform(),
|
||||
glm::vec3 {-mScrollOffset2, 0.0f, 0.0f});
|
||||
renderFunc(trans);
|
||||
glm::vec3 {offsetX - mScrollOffset2, 0.0f, 0.0f});
|
||||
renderFunc(trans, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (mHorizontalScrolling && mTextCache != nullptr)
|
||||
mRenderer->popClipRect();
|
||||
}
|
||||
|
||||
void TextComponent::setValue(const std::string& value)
|
||||
|
@ -347,9 +379,9 @@ void TextComponent::update(int deltaTime)
|
|||
mScrollOffset1 = 0.0f;
|
||||
mScrollOffset2 = 0.0f;
|
||||
|
||||
if (mTextCache->metrics.size.x > mSize.x) {
|
||||
if (mTextCache->metrics.size.x > mSize.x * mRelativeScale) {
|
||||
const float scrollLength {mTextCache->metrics.size.x};
|
||||
const float returnLength {mScrollSpeed * 1.5f / mScrollSpeedMultiplier};
|
||||
const float returnLength {mScrollSpeed * mScrollGap / mScrollSpeedMultiplier};
|
||||
const float scrollTime {(scrollLength * 1000.0f) / mScrollSpeed};
|
||||
const float returnTime {(returnLength * 1000.0f) / mScrollSpeed};
|
||||
const float maxTime {mScrollDelay + scrollTime + returnTime};
|
||||
|
@ -362,7 +394,7 @@ void TextComponent::update(int deltaTime)
|
|||
mScrollOffset1 = Utils::Math::loop(mScrollDelay, scrollTime + returnTime, mScrollTime,
|
||||
scrollLength + returnLength);
|
||||
|
||||
if (mScrollOffset1 > (scrollLength - (mSize.x - returnLength)))
|
||||
if (mScrollOffset1 > (scrollLength - (mSize.x * mRelativeScale - returnLength)))
|
||||
mScrollOffset2 = mScrollOffset1 - (scrollLength + returnLength);
|
||||
else if (mScrollOffset2 < 0)
|
||||
mScrollOffset2 = 0;
|
||||
|
@ -392,7 +424,6 @@ void TextComponent::onTextChanged()
|
|||
|
||||
if (mFont && mAutoCalcExtent.x) {
|
||||
mSize = mFont->sizeText(text, mLineSpacing);
|
||||
// This can happen under special circumstances like when a blank/dummy font is used.
|
||||
if (mSize.x == 0.0f)
|
||||
return;
|
||||
}
|
||||
|
@ -407,18 +438,20 @@ void TextComponent::onTextChanged()
|
|||
// Used to initialize all glyphs, which is needed to populate mMaxGlyphHeight.
|
||||
lineHeight = mFont->loadGlyphs(text + "\n") * mLineSpacing;
|
||||
|
||||
const bool isMultiline {mAutoCalcExtent.y == 1 || mSize.y > lineHeight};
|
||||
const bool isMultiline {mAutoCalcExtent.y == 1 || mSize.y * mRelativeScale > lineHeight};
|
||||
|
||||
if (mHorizontalScrolling) {
|
||||
mTextCache = std::shared_ptr<TextCache>(font->buildTextCache(text, 0.0f, 0.0f, mColor));
|
||||
mTextCache = std::shared_ptr<TextCache>(
|
||||
font->buildTextCache(text, 0.0f, 0.0f, mColor, mLineSpacing));
|
||||
}
|
||||
else if (isMultiline && !isScrollable) {
|
||||
const std::string wrappedText {
|
||||
font->wrapText(text, mSize.x, (mVerticalAutoSizing ? 0.0f : mSize.y - lineHeight),
|
||||
font->wrapText(text, mSize.x * mRelativeScale,
|
||||
(mVerticalAutoSizing ? 0.0f : (mSize.y * mRelativeScale) - lineHeight),
|
||||
mLineSpacing, isMultiline)};
|
||||
mTextCache = std::shared_ptr<TextCache>(
|
||||
font->buildTextCache(wrappedText, glm::vec2 {0.0f, 0.0f}, mColor, mSize.x,
|
||||
mHorizontalAlignment, mLineSpacing, mNoTopMargin));
|
||||
mTextCache = std::shared_ptr<TextCache>(font->buildTextCache(
|
||||
wrappedText, glm::vec2 {0.0f, 0.0f}, mColor, mSize.x * mRelativeScale,
|
||||
mHorizontalAlignment, mLineSpacing, mNoTopMargin));
|
||||
}
|
||||
else {
|
||||
mTextCache = std::shared_ptr<TextCache>(font->buildTextCache(
|
||||
|
@ -563,8 +596,6 @@ void TextComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
glm::clamp(elem->get<float>("containerStartDelay"), 0.0f, 10.0f) * 1000.0f;
|
||||
}
|
||||
mHorizontalScrolling = true;
|
||||
// Rotation can't be combined with a scrolling horizontal container.
|
||||
mRotation = 0.0f;
|
||||
}
|
||||
else if (containerType != "vertical") {
|
||||
LOG(LogError) << "TextComponent: Invalid theme configuration, property "
|
||||
|
|
|
@ -29,7 +29,13 @@ public:
|
|||
Alignment verticalAlignment = ALIGN_CENTER,
|
||||
glm::vec3 pos = {0.0f, 0.0f, 0.0f},
|
||||
glm::vec2 size = {0.0f, 0.0f},
|
||||
unsigned int bgcolor = 0x00000000);
|
||||
unsigned int bgcolor = 0x00000000,
|
||||
float lineSpacing = 1.5f,
|
||||
float relativeScale = 1.0f,
|
||||
bool horizontalScrolling = false,
|
||||
float scrollSpeedMultiplier = 1.0f,
|
||||
float scrollDelay = 1500.0f,
|
||||
float scrollGap = 1.5f);
|
||||
|
||||
void setFont(const std::shared_ptr<Font>& font);
|
||||
void setUppercase(bool uppercase);
|
||||
|
@ -91,6 +97,7 @@ public:
|
|||
void setHorizontalScrolling(bool state) override;
|
||||
void setHorizontalScrollingSpeedMultiplier(float speed) { mScrollSpeedMultiplier = speed; }
|
||||
void setHorizontalScrollingDelay(float delay) { mScrollDelay = delay; }
|
||||
void setHorizontalScrollingGap(float gap) { mScrollGap = gap; }
|
||||
|
||||
void resetComponent() override
|
||||
{
|
||||
|
@ -143,6 +150,7 @@ private:
|
|||
Alignment mHorizontalAlignment;
|
||||
Alignment mVerticalAlignment;
|
||||
float mLineSpacing;
|
||||
float mRelativeScale;
|
||||
bool mNoTopMargin;
|
||||
bool mSelectable;
|
||||
bool mVerticalAutoSizing;
|
||||
|
@ -151,6 +159,7 @@ private:
|
|||
float mScrollSpeed;
|
||||
float mScrollSpeedMultiplier;
|
||||
float mScrollDelay;
|
||||
float mScrollGap;
|
||||
float mScrollOffset1;
|
||||
float mScrollOffset2;
|
||||
float mScrollTime;
|
||||
|
|
|
@ -28,6 +28,7 @@ protected:
|
|||
using List = IList<CarouselEntry, T>;
|
||||
using List::mCursor;
|
||||
using List::mEntries;
|
||||
using List::mLastCursor;
|
||||
using List::mScrollVelocity;
|
||||
using List::mSize;
|
||||
using List::mWindow;
|
||||
|
@ -99,6 +100,7 @@ public:
|
|||
unsigned int properties) override;
|
||||
|
||||
private:
|
||||
void onShowPrimary() override { mEntries.at(mCursor).data.item->resetComponent(); }
|
||||
void onCursorChanged(const CursorState& state) override;
|
||||
void onScroll() override
|
||||
{
|
||||
|
@ -192,11 +194,15 @@ private:
|
|||
unsigned int mCarouselColor;
|
||||
unsigned int mCarouselColorEnd;
|
||||
bool mColorGradientHorizontal;
|
||||
float mTextRelativeScale;
|
||||
unsigned int mTextColor;
|
||||
unsigned int mTextBackgroundColor;
|
||||
unsigned int mTextSelectedColor;
|
||||
unsigned int mTextSelectedBackgroundColor;
|
||||
bool mHasTextSelectedColor;
|
||||
bool mTextHorizontalScrolling;
|
||||
float mTextHorizontalScrollSpeed;
|
||||
float mTextHorizontalScrollDelay;
|
||||
std::shared_ptr<Font> mFont;
|
||||
LetterCase mLetterCase;
|
||||
LetterCase mLetterCaseAutoCollections;
|
||||
|
@ -262,11 +268,15 @@ CarouselComponent<T>::CarouselComponent()
|
|||
, mCarouselColor {0}
|
||||
, mCarouselColorEnd {0}
|
||||
, mColorGradientHorizontal {true}
|
||||
, mTextRelativeScale {1.0f}
|
||||
, mTextColor {0x000000FF}
|
||||
, mTextBackgroundColor {0xFFFFFF00}
|
||||
, mTextSelectedColor {0x000000FF}
|
||||
, mTextSelectedBackgroundColor {0xFFFFFF00}
|
||||
, mHasTextSelectedColor {false}
|
||||
, mTextHorizontalScrolling {false}
|
||||
, mTextHorizontalScrollSpeed {1.0f}
|
||||
, mTextHorizontalScrollDelay {3000.0f}
|
||||
, mFont {Font::get(FONT_SIZE_LARGE_FIXED)}
|
||||
, mLetterCase {LetterCase::NONE}
|
||||
, mLetterCaseAutoCollections {LetterCase::UNDEFINED}
|
||||
|
@ -354,8 +364,9 @@ void CarouselComponent<T>::addEntry(Entry& entry, const std::shared_ptr<ThemeDat
|
|||
auto text = std::make_shared<TextComponent>(
|
||||
entry.name, mFont, 0x000000FF, mItemHorizontalAlignment, mItemVerticalAlignment,
|
||||
glm::vec3 {0.0f, 0.0f, 0.0f},
|
||||
glm::round(mItemSize * (mItemScale >= 1.0f ? mItemScale : 1.0f)), 0x00000000);
|
||||
text->setLineSpacing(mLineSpacing);
|
||||
glm::round(mItemSize * (mItemScale >= 1.0f ? mItemScale : 1.0f)), 0x00000000,
|
||||
mLineSpacing, mTextRelativeScale, mTextHorizontalScrolling, mTextHorizontalScrollSpeed,
|
||||
mTextHorizontalScrollDelay, 1.0f);
|
||||
if (!mGamelistView)
|
||||
text->setValue(entry.name);
|
||||
text->setColor(mTextColor);
|
||||
|
@ -654,6 +665,7 @@ template <typename T> bool CarouselComponent<T>::input(InputConfig* config, Inpu
|
|||
|
||||
template <typename T> void CarouselComponent<T>::update(int deltaTime)
|
||||
{
|
||||
mEntries.at(mCursor).data.item->update(deltaTime);
|
||||
List::listUpdate(deltaTime);
|
||||
GuiComponent::update(deltaTime);
|
||||
}
|
||||
|
@ -1646,6 +1658,9 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
mFont = Font::getFromTheme(elem, properties, mFont, 0.0f, false,
|
||||
(mItemScale >= 1.0f ? mItemScale : 1.0f));
|
||||
|
||||
if (elem->has("textRelativeScale"))
|
||||
mTextRelativeScale = glm::clamp(elem->get<float>("textRelativeScale"), 0.2f, 1.0f);
|
||||
|
||||
if (elem->has("textColor"))
|
||||
mTextColor = elem->get<unsigned int>("textColor");
|
||||
if (elem->has("textBackgroundColor"))
|
||||
|
@ -1663,6 +1678,19 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
mHasTextSelectedColor = true;
|
||||
}
|
||||
|
||||
if (elem->has("textHorizontalScrolling"))
|
||||
mTextHorizontalScrolling = elem->get<bool>("textHorizontalScrolling");
|
||||
|
||||
if (elem->has("textHorizontalScrollSpeed")) {
|
||||
mTextHorizontalScrollSpeed =
|
||||
glm::clamp(elem->get<float>("textHorizontalScrollSpeed"), 0.1f, 10.0f);
|
||||
}
|
||||
|
||||
if (elem->has("textHorizontalScrollDelay")) {
|
||||
mTextHorizontalScrollDelay =
|
||||
glm::clamp(elem->get<float>("textHorizontalScrollDelay"), 0.0f, 10.0f) * 1000.0f;
|
||||
}
|
||||
|
||||
if (elem->has("lineSpacing"))
|
||||
mLineSpacing = glm::clamp(elem->get<float>("lineSpacing"), 0.5f, 3.0f);
|
||||
|
||||
|
@ -1763,6 +1791,9 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
|
||||
template <typename T> void CarouselComponent<T>::onCursorChanged(const CursorState& state)
|
||||
{
|
||||
if (mEntries.size() > static_cast<size_t>(mLastCursor))
|
||||
mEntries.at(mLastCursor).data.item->resetComponent();
|
||||
|
||||
float startPos {mEntryCamOffset};
|
||||
float posMax {static_cast<float>(mEntries.size())};
|
||||
float target {static_cast<float>(mCursor)};
|
||||
|
|
|
@ -84,6 +84,7 @@ public:
|
|||
unsigned int properties) override;
|
||||
|
||||
private:
|
||||
void onShowPrimary() override { mEntries.at(mCursor).data.item->resetComponent(); }
|
||||
void onScroll() override
|
||||
{
|
||||
if (mGamelistView)
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
virtual int size() const = 0;
|
||||
|
||||
// Functions used by all primary components.
|
||||
virtual void onShowPrimary() = 0;
|
||||
virtual void setCancelTransitionsCallback(const std::function<void()>& func) = 0;
|
||||
virtual void setCursorChangedCallback(const std::function<void(CursorState state)>& func) = 0;
|
||||
virtual int getCursor() = 0;
|
||||
|
|
|
@ -85,7 +85,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void onShow() override { mEntries.at(mCursor).data.entryName->resetComponent(); }
|
||||
void onShowPrimary() override { mEntries.at(mCursor).data.entryName->resetComponent(); }
|
||||
void onScroll() override
|
||||
{
|
||||
if (mGamelistView &&
|
||||
|
@ -278,8 +278,8 @@ template <typename T> bool TextListComponent<T>::input(InputConfig* config, Inpu
|
|||
|
||||
template <typename T> void TextListComponent<T>::update(int deltaTime)
|
||||
{
|
||||
mEntries.at(mCursor).data.entryName->update(deltaTime);
|
||||
List::listUpdate(deltaTime);
|
||||
mEntries.at(static_cast<unsigned int>(mCursor)).data.entryName->update(deltaTime);
|
||||
GuiComponent::update(deltaTime);
|
||||
}
|
||||
|
||||
|
|
|
@ -222,6 +222,7 @@ TextCache* Font::buildTextCache(const std::string& text,
|
|||
cache->vertexLists.resize(vertMap.size());
|
||||
cache->metrics.size = {sizeText(text, lineSpacing)};
|
||||
cache->metrics.maxGlyphHeight = mMaxGlyphHeight;
|
||||
cache->clipRegion = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
size_t i {0};
|
||||
for (auto it = vertMap.cbegin(); it != vertMap.cend(); ++it) {
|
||||
|
@ -242,12 +243,18 @@ void Font::renderTextCache(TextCache* cache)
|
|||
return;
|
||||
}
|
||||
|
||||
const bool clipRegion {cache->clipRegion != glm::vec4 {0.0f, 0.0f, 0.0f, 0.0f}};
|
||||
|
||||
for (auto it = cache->vertexLists.begin(); it != cache->vertexLists.end(); ++it) {
|
||||
assert(*it->textureIdPtr != 0);
|
||||
|
||||
auto vertexList = *it;
|
||||
it->verts[0].shaderFlags = Renderer::ShaderFlags::FONT_TEXTURE;
|
||||
|
||||
if (clipRegion) {
|
||||
it->verts[0].shaderFlags |= Renderer::ShaderFlags::CLIPPING;
|
||||
it->verts[0].clipregion = cache->clipRegion;
|
||||
}
|
||||
|
||||
mRenderer->bindTexture(*it->textureIdPtr);
|
||||
mRenderer->drawTriangleStrips(
|
||||
&it->verts[0], static_cast<const unsigned int>(it->verts.size()),
|
||||
|
|
|
@ -239,6 +239,7 @@ public:
|
|||
void setOpacity(float opacity);
|
||||
void setSaturation(float saturation);
|
||||
void setDimming(float dimming);
|
||||
void setClipRegion(const glm::vec4& clip) { clipRegion = clip; }
|
||||
const glm::vec2& getSize() { return metrics.size; }
|
||||
|
||||
friend Font;
|
||||
|
@ -250,6 +251,7 @@ protected:
|
|||
};
|
||||
|
||||
std::vector<VertexList> vertexLists;
|
||||
glm::vec4 clipRegion;
|
||||
};
|
||||
|
||||
#endif // ES_CORE_RESOURCES_FONT_H
|
||||
|
|
Loading…
Reference in a new issue