Enabled vertical abbreviations of multiline text entries in TextComponent.

Also fixed an issue where the debug overlay would not get rendered correctly for scrollable containers.
This commit is contained in:
Leon Styhre 2022-08-21 16:51:21 +02:00
parent ce217c48a4
commit 08d5e4eff0
4 changed files with 32 additions and 14 deletions

View file

@ -253,6 +253,7 @@ public:
// Used to set the parameters for ScrollableContainer. // Used to set the parameters for ScrollableContainer.
virtual void setScrollParameters(float, float, float) {} virtual void setScrollParameters(float, float, float) {}
virtual const bool isScrollable() const { return false; }
virtual void onFocusGained() {} virtual void onFocusGained() {}
virtual void onFocusLost() {} virtual void onFocusLost() {}

View file

@ -239,6 +239,9 @@ void ScrollableContainer::render(const glm::mat4& parentTrans)
trans = glm::translate(trans, -glm::vec3 {mScrollPos.x, mScrollPos.y, 0.0f}); trans = glm::translate(trans, -glm::vec3 {mScrollPos.x, mScrollPos.y, 0.0f});
mRenderer->setMatrix(trans); mRenderer->setMatrix(trans);
if (Settings::getInstance()->getBool("DebugText"))
mRenderer->drawRect(0.0f, mScrollPos.y, mSize.x, mSize.y, 0x0000FF33, 0x0000FF33);
GuiComponent::renderChildren(trans); GuiComponent::renderChildren(trans);
mRenderer->popClipRect(); mRenderer->popClipRect();
} }

View file

@ -28,6 +28,8 @@ public:
glm::vec2 getScrollPos() const { return mScrollPos; } glm::vec2 getScrollPos() const { return mScrollPos; }
void setScrollPos(const glm::vec2& pos) { mScrollPos = pos; } void setScrollPos(const glm::vec2& pos) { mScrollPos = pos; }
const bool isScrollable() const override { return true; }
void setAutoScroll(bool autoScroll); void setAutoScroll(bool autoScroll);
void setScrollParameters(float autoScrollDelayConstant, void setScrollParameters(float autoScrollDelayConstant,
float autoScrollResetDelayConstant, float autoScrollResetDelayConstant,

View file

@ -159,7 +159,7 @@ void TextComponent::setCapitalize(bool capitalize)
void TextComponent::render(const glm::mat4& parentTrans) void TextComponent::render(const glm::mat4& parentTrans)
{ {
if (!isVisible() || mThemeOpacity == 0.0f) if (!isVisible() || mThemeOpacity == 0.0f || mSize.x == 0.0f || mSize.y == 0.0f)
return; return;
glm::mat4 trans {parentTrans * getTransform()}; glm::mat4 trans {parentTrans * getTransform()};
@ -197,9 +197,12 @@ void TextComponent::render(const glm::mat4& parentTrans)
yOff = (getSize().y - textSize.y) / 2.0f; yOff = (getSize().y - textSize.y) / 2.0f;
} }
// Draw the "textbox" area, what we are aligned within. // Draw the overall textbox area. If we're inside a scrollable container then this
if (Settings::getInstance()->getBool("DebugText")) // area is rendered inside that component instead of here.
if (Settings::getInstance()->getBool("DebugText")) {
if (!mParent || !mParent->isScrollable())
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0x0000FF33, 0x0000FF33); mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0x0000FF33, 0x0000FF33);
}
trans = glm::translate(trans, glm::vec3 {0.0f, std::round(yOff), 0.0f}); trans = glm::translate(trans, glm::vec3 {0.0f, std::round(yOff), 0.0f});
@ -279,7 +282,7 @@ void TextComponent::onTextChanged()
{ {
calculateExtent(); calculateExtent();
if (!mFont || mText.empty()) { if (!mFont || mText.empty() || mSize.x == 0.0f || mSize.y == 0.0f) {
mTextCache.reset(); mTextCache.reset();
return; return;
} }
@ -295,25 +298,27 @@ void TextComponent::onTextChanged()
else else
text = mText; // Original case. text = mText; // Original case.
std::shared_ptr<Font> f = mFont; std::shared_ptr<Font> f {mFont};
const bool isMultiline = (mSize.y == 0.0f || mSize.y > f->getHeight() * 1.2f); const float lineHeight {f->getHeight(mLineSpacing)};
const bool isMultiline {mSize.y > lineHeight};
const bool isScrollable {mParent && mParent->isScrollable()};
bool addAbbrev = false; bool addAbbrev {false};
if (!isMultiline) { if (!isMultiline) {
size_t newline = text.find('\n'); size_t newline {text.find('\n')};
// Single line of text - stop at the first newline since it'll mess everything up. // Single line of text - stop at the first newline since it'll mess everything up.
text = text.substr(0, newline); text = text.substr(0, newline);
addAbbrev = newline != std::string::npos; addAbbrev = newline != std::string::npos;
} }
glm::vec2 size {f->sizeText(text)}; glm::vec2 size {f->sizeText(text)};
if (!isMultiline && mSize.x > 0.0f && text.size() && (size.x > mSize.x || addAbbrev)) { if (!isMultiline && text.size() && (size.x > mSize.x || addAbbrev)) {
// Abbreviate text. // Abbreviate text.
const std::string abbrev = "..."; const std::string abbrev {"..."};
glm::vec2 abbrevSize {f->sizeText(abbrev)}; float abbrevSize {f->sizeText(abbrev).x};
while (text.size() && size.x + abbrevSize.x > mSize.x) { while (text.size() && size.x + abbrevSize > mSize.x) {
size_t newSize = Utils::String::prevCursor(text, text.size()); size_t newSize {Utils::String::prevCursor(text, text.size())};
text.erase(newSize, text.size() - newSize); text.erase(newSize, text.size() - newSize);
if (!text.empty() && text.back() == ' ') if (!text.empty() && text.back() == ' ')
text.pop_back(); text.pop_back();
@ -324,6 +329,13 @@ void TextComponent::onTextChanged()
mTextCache = std::shared_ptr<TextCache>(f->buildTextCache( mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(
text, glm::vec2 {}, mColor, mSize.x, mHorizontalAlignment, mLineSpacing, mNoTopMargin)); text, glm::vec2 {}, mColor, mSize.x, mHorizontalAlignment, mLineSpacing, mNoTopMargin));
} }
else if (isMultiline && text.size() && !isScrollable) {
const std::string wrappedText {
f->wrapText(text, mSize.x, mSize.y - lineHeight, mLineSpacing)};
mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(wrappedText, glm::vec2 {}, mColor,
mSize.x, mHorizontalAlignment,
mLineSpacing, mNoTopMargin));
}
else { else {
mTextCache = std::shared_ptr<TextCache>( mTextCache = std::shared_ptr<TextCache>(
f->buildTextCache(f->wrapText(text, mSize.x), glm::vec2 {}, mColor, mSize.x, f->buildTextCache(f->wrapText(text, mSize.x), glm::vec2 {}, mColor, mSize.x,