mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-18 07:05:39 +00:00
Finally added scrolling description text. :)
This commit is contained in:
parent
3971fdc674
commit
ec7ad28fdc
|
@ -43,6 +43,7 @@ namespace Renderer
|
||||||
void drawText(std::string text, int x, int y, unsigned int color, Font* font);
|
void drawText(std::string text, int x, int y, unsigned int color, Font* font);
|
||||||
void drawCenteredText(std::string text, int xOffset, int y, unsigned int color, Font* font);
|
void drawCenteredText(std::string text, int xOffset, int y, unsigned int color, Font* font);
|
||||||
void drawWrappedText(std::string text, int xStart, int yStart, int xLen, unsigned int color, Font* font);
|
void drawWrappedText(std::string text, int xStart, int yStart, int xLen, unsigned int color, Font* font);
|
||||||
|
void sizeWrappedText(std::string text, int xLen, Font* font, int* xOut, int* yOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -252,4 +252,61 @@ namespace Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sizeWrappedText(std::string text, int xLen, Font* font, int* xOut, int* yOut)
|
||||||
|
{
|
||||||
|
*xOut = xLen;
|
||||||
|
|
||||||
|
int y = 0;
|
||||||
|
|
||||||
|
std::string line, word, temp;
|
||||||
|
int w, h;
|
||||||
|
size_t space, newline;
|
||||||
|
|
||||||
|
while(text.length() > 0 || !line.empty()) //while there's text or we still have text to render
|
||||||
|
{
|
||||||
|
space = text.find(' ', 0);
|
||||||
|
if(space == std::string::npos)
|
||||||
|
space = text.length() - 1;
|
||||||
|
|
||||||
|
word = text.substr(0, space + 1);
|
||||||
|
|
||||||
|
//check if the next word contains a newline
|
||||||
|
newline = word.find('\n', 0);
|
||||||
|
if(newline != std::string::npos)
|
||||||
|
{
|
||||||
|
word = word.substr(0, newline);
|
||||||
|
text.erase(0, newline + 1);
|
||||||
|
}else{
|
||||||
|
text.erase(0, space + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = line + word;
|
||||||
|
|
||||||
|
font->sizeText(temp, &w, &h);
|
||||||
|
|
||||||
|
//if we're on the last word and it'll fit on the line, just add it to the line
|
||||||
|
if((w <= xLen && text.length() == 0) || newline != std::string::npos)
|
||||||
|
{
|
||||||
|
line = temp;
|
||||||
|
word = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//if the next line will be too long or we're on the last of the text, render it
|
||||||
|
if(w > xLen || text.length() == 0 || newline != std::string::npos)
|
||||||
|
{
|
||||||
|
//increment y by height and some extra padding for the next line
|
||||||
|
y += h + 4;
|
||||||
|
|
||||||
|
//move the word we skipped to the next line
|
||||||
|
line = word;
|
||||||
|
}else{
|
||||||
|
//there's still space, continue building the line
|
||||||
|
line = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*yOut = y;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -93,6 +93,7 @@ bool operator !=(const Vector2<T>& left, const Vector2<T>& right)
|
||||||
typedef Vector2<int> Vector2i;
|
typedef Vector2<int> Vector2i;
|
||||||
typedef Vector2<unsigned int> Vector2u;
|
typedef Vector2<unsigned int> Vector2u;
|
||||||
typedef Vector2<float> Vector2f;
|
typedef Vector2<float> Vector2f;
|
||||||
|
typedef Vector2<double> Vector2d;
|
||||||
|
|
||||||
class Rect
|
class Rect
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,8 +36,10 @@ GuiGameList::GuiGameList(Window* window, bool useDetail) : GuiComponent(window),
|
||||||
|
|
||||||
mScreenshot->setOrigin(mTheme->getFloat("gameImageOriginX"), mTheme->getFloat("gameImageOriginY"));
|
mScreenshot->setOrigin(mTheme->getFloat("gameImageOriginX"), mTheme->getFloat("gameImageOriginY"));
|
||||||
|
|
||||||
mDescription.setOffset(Vector2i((int)(Renderer::getScreenWidth() * 0.03), mScreenshot->getOffset().y + mScreenshot->getSize().y + 12));
|
mDescription.setOffset(Vector2i((int)(Renderer::getScreenWidth() * 0.03), getImagePos().y + mScreenshot->getSize().y + 12));
|
||||||
mDescription.setExtent(Vector2u((int)(Renderer::getScreenWidth() * (mTheme->getFloat("listOffsetX") - 0.03)), 0));
|
//scale delay with screen width (higher width = more text per line)
|
||||||
|
//the scroll speed is automatically scrolled by component size
|
||||||
|
mDescription.setAutoScroll((int)(1500 + (Renderer::getScreenWidth() * 0.5)), 0.025f);
|
||||||
|
|
||||||
mTransitionImage.setOffset(Renderer::getScreenWidth(), 0);
|
mTransitionImage.setOffset(Renderer::getScreenWidth(), 0);
|
||||||
mTransitionImage.setOrigin(0, 0);
|
mTransitionImage.setOrigin(0, 0);
|
||||||
|
@ -307,7 +309,8 @@ void GuiGameList::updateDetailData()
|
||||||
mImageAnimation->fadeIn(35);
|
mImageAnimation->fadeIn(35);
|
||||||
mImageAnimation->move(imgOffset.x, imgOffset.y, 20);
|
mImageAnimation->move(imgOffset.x, imgOffset.y, 20);
|
||||||
|
|
||||||
mDescription.setOffset(Vector2i((int)(Renderer::getScreenWidth() * 0.03), mScreenshot->getOffset().y + mScreenshot->getSize().y + 12));
|
mDescription.setOffset(Vector2i((int)(Renderer::getScreenWidth() * 0.03), getImagePos().y + mScreenshot->getSize().y + 12));
|
||||||
|
mDescription.setExtent(Vector2u((int)(Renderer::getScreenWidth() * (mTheme->getFloat("listOffsetX") - 0.03)), Renderer::getScreenHeight() - mDescription.getOffset().y));
|
||||||
mDescription.setText(((GameData*)mList->getSelectedObject())->getDescription());
|
mDescription.setText(((GameData*)mList->getSelectedObject())->getDescription());
|
||||||
}else{
|
}else{
|
||||||
mScreenshot->setImage("");
|
mScreenshot->setImage("");
|
||||||
|
@ -373,6 +376,8 @@ void GuiGameList::update(int deltaTime)
|
||||||
mTransitionAnimation.update(deltaTime);
|
mTransitionAnimation.update(deltaTime);
|
||||||
|
|
||||||
mList->update(deltaTime);
|
mList->update(deltaTime);
|
||||||
|
|
||||||
|
mDescription.update(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiGameList::doTransition(int dir)
|
void GuiGameList::doTransition(int dir)
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
#include "../Renderer.h"
|
#include "../Renderer.h"
|
||||||
#include "../Log.h"
|
#include "../Log.h"
|
||||||
|
|
||||||
TextComponent::TextComponent(Window* window) : GuiComponent(window), mFont(NULL), mColor(0x000000FF), mAutoCalcExtent(true)
|
TextComponent::TextComponent(Window* window) : GuiComponent(window),
|
||||||
|
mFont(NULL), mColor(0x000000FF), mAutoCalcExtent(true), mAutoScrollDelay(0), mAutoScrollSpeed(0), mAutoScrollTimer(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TextComponent::TextComponent(Window* window, const std::string& text, Font* font, Vector2i pos, Vector2u size) : GuiComponent(window),
|
TextComponent::TextComponent(Window* window, const std::string& text, Font* font, Vector2i pos, Vector2u size) : GuiComponent(window),
|
||||||
mFont(NULL), mColor(0x000000FF), mAutoCalcExtent(true)
|
mFont(NULL), mColor(0x000000FF), mAutoCalcExtent(true), mAutoScrollDelay(0), mAutoScrollSpeed(0), mAutoScrollTimer(0)
|
||||||
{
|
{
|
||||||
setText(text);
|
setText(text);
|
||||||
setFont(font);
|
setFont(font);
|
||||||
|
@ -51,11 +52,20 @@ void TextComponent::setText(const std::string& text)
|
||||||
|
|
||||||
if(mAutoCalcExtent)
|
if(mAutoCalcExtent)
|
||||||
calculateExtent();
|
calculateExtent();
|
||||||
|
|
||||||
|
mScrollPos = Vector2d(0, 0);
|
||||||
|
mScrollDir = Vector2d(0, 0);
|
||||||
|
resetAutoScrollTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
Font* TextComponent::getFont() const
|
||||||
|
{
|
||||||
|
return (mFont ? mFont : Renderer::getDefaultFont(Renderer::MEDIUM));;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextComponent::onRender()
|
void TextComponent::onRender()
|
||||||
{
|
{
|
||||||
Font* font = (mFont ? mFont : Renderer::getDefaultFont(Renderer::MEDIUM));
|
Font* font = getFont();
|
||||||
if(font == NULL)
|
if(font == NULL)
|
||||||
{
|
{
|
||||||
LOG(LogError) << "TextComponent can't get a valid font!";
|
LOG(LogError) << "TextComponent can't get a valid font!";
|
||||||
|
@ -64,7 +74,7 @@ void TextComponent::onRender()
|
||||||
|
|
||||||
Renderer::pushClipRect(getGlobalOffset(), getSize());
|
Renderer::pushClipRect(getGlobalOffset(), getSize());
|
||||||
|
|
||||||
Renderer::drawWrappedText(mText, 0, 0, mSize.x, mColor, font);
|
Renderer::drawWrappedText(mText, (int)-mScrollPos.x, (int)-mScrollPos.y, mSize.x, mColor, font);
|
||||||
|
|
||||||
Renderer::popClipRect();
|
Renderer::popClipRect();
|
||||||
|
|
||||||
|
@ -73,7 +83,7 @@ void TextComponent::onRender()
|
||||||
|
|
||||||
void TextComponent::calculateExtent()
|
void TextComponent::calculateExtent()
|
||||||
{
|
{
|
||||||
Font* font = (mFont ? mFont : Renderer::getDefaultFont(Renderer::MEDIUM));
|
Font* font = getFont();
|
||||||
if(font == NULL)
|
if(font == NULL)
|
||||||
{
|
{
|
||||||
LOG(LogError) << "TextComponent can't get a valid font!";
|
LOG(LogError) << "TextComponent can't get a valid font!";
|
||||||
|
@ -82,3 +92,73 @@ void TextComponent::calculateExtent()
|
||||||
|
|
||||||
font->sizeText(mText, (int*)&mSize.x, (int*)&mSize.y);
|
font->sizeText(mText, (int*)&mSize.x, (int*)&mSize.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextComponent::setAutoScroll(int delay, double speed)
|
||||||
|
{
|
||||||
|
mAutoScrollDelay = delay;
|
||||||
|
mAutoScrollSpeed = speed;
|
||||||
|
resetAutoScrollTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextComponent::resetAutoScrollTimer()
|
||||||
|
{
|
||||||
|
mAutoScrollTimer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2d TextComponent::getScrollPos() const
|
||||||
|
{
|
||||||
|
return mScrollPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextComponent::setScrollPos(const Vector2d& pos)
|
||||||
|
{
|
||||||
|
mScrollPos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextComponent::update(int deltaTime)
|
||||||
|
{
|
||||||
|
double scrollAmt = (double)deltaTime;
|
||||||
|
|
||||||
|
if(mAutoScrollSpeed != 0)
|
||||||
|
{
|
||||||
|
mAutoScrollTimer += deltaTime;
|
||||||
|
|
||||||
|
scrollAmt = (float)(mAutoScrollTimer - mAutoScrollDelay);
|
||||||
|
|
||||||
|
if(scrollAmt > 0)
|
||||||
|
{
|
||||||
|
//scroll the amount of time left over from the delay
|
||||||
|
mAutoScrollTimer = mAutoScrollDelay;
|
||||||
|
|
||||||
|
//scale speed by our width! more text per line = slower scrolling
|
||||||
|
const double widthMod = (680.0 / getSize().x);
|
||||||
|
mScrollDir = Vector2d(0, mAutoScrollSpeed * widthMod);
|
||||||
|
}else{
|
||||||
|
//not enough to pass the delay, do nothing
|
||||||
|
scrollAmt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2d scroll = mScrollDir * scrollAmt;
|
||||||
|
mScrollPos += scroll;
|
||||||
|
|
||||||
|
//clip scrolling within bounds
|
||||||
|
if(mScrollPos.x < 0)
|
||||||
|
mScrollPos.x = 0;
|
||||||
|
if(mScrollPos.y < 0)
|
||||||
|
mScrollPos.y = 0;
|
||||||
|
|
||||||
|
Font* font = getFont();
|
||||||
|
if(font != NULL)
|
||||||
|
{
|
||||||
|
Vector2i textSize;
|
||||||
|
Renderer::sizeWrappedText(mText, getSize().x, getFont(), &textSize.x, &textSize.y);
|
||||||
|
|
||||||
|
if(mScrollPos.x + getSize().x > textSize.x)
|
||||||
|
mScrollPos.x = (double)textSize.x - getSize().x;
|
||||||
|
if(mScrollPos.y + getSize().y > textSize.y)
|
||||||
|
mScrollPos.y = (double)textSize.y - getSize().y;
|
||||||
|
}
|
||||||
|
|
||||||
|
GuiComponent::update(deltaTime);
|
||||||
|
}
|
||||||
|
|
|
@ -16,15 +16,29 @@ public:
|
||||||
void setText(const std::string& text);
|
void setText(const std::string& text);
|
||||||
void setColor(unsigned int color);
|
void setColor(unsigned int color);
|
||||||
|
|
||||||
void onRender();
|
Vector2d getScrollPos() const;
|
||||||
|
void setScrollPos(const Vector2d& pos);
|
||||||
|
void setAutoScroll(int delay, double speed); //Use 0 for speed to disable.
|
||||||
|
void resetAutoScrollTimer();
|
||||||
|
|
||||||
|
void update(int deltaTime) override;
|
||||||
|
void onRender() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Font* getFont() const;
|
||||||
void calculateExtent();
|
void calculateExtent();
|
||||||
|
|
||||||
unsigned int mColor;
|
unsigned int mColor;
|
||||||
Font* mFont;
|
Font* mFont;
|
||||||
bool mAutoCalcExtent;
|
bool mAutoCalcExtent;
|
||||||
std::string mText;
|
std::string mText;
|
||||||
|
|
||||||
|
//scrolling
|
||||||
|
Vector2d mScrollPos;
|
||||||
|
Vector2d mScrollDir;
|
||||||
|
int mAutoScrollDelay;
|
||||||
|
double mAutoScrollSpeed;
|
||||||
|
int mAutoScrollTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue