Finally added scrolling description text. :)

This commit is contained in:
Aloshi 2013-07-02 00:57:31 -05:00
parent 3971fdc674
commit ec7ad28fdc
6 changed files with 168 additions and 10 deletions

View file

@ -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

View file

@ -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;
}
}; };

View file

@ -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
{ {

View file

@ -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)

View file

@ -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);
}

View file

@ -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