Improved Vertical Scrolling

This commit is contained in:
techdragon.nguyen@gmail.com
2010-11-28 23:54:36 +00:00
parent 3205ebdc8b
commit 8fd35ac513
7 changed files with 70 additions and 47 deletions

View File

@@ -48,7 +48,7 @@ protected:
bool mClosed; bool mClosed;
public: public:
TextScroller * mScroller; VerticalTextScroller * mScroller;
bool mAutoTranslate; bool mAutoTranslate;
float mSelectionTargetY; float mSelectionTargetY;

View File

@@ -41,11 +41,11 @@ private:
size_t mNbItemsShown; size_t mNbItemsShown;
bool mScrollerInitialized; bool mScrollerInitialized;
float mHeight; // maximum height availble for display float mHeight; // maximum height availble for display
int mMarginX; float mMarginX;
int mMarginY; // margin used to allow text to scroll off screen without float mMarginY; // margin used to allow text to scroll off screen without
// affecting look and feel. Should be enough // affecting look and feel. Should be enough
// for at least one line of text ( marginY) // for at least one line of text ( mY - line height of current font )
float mVerticalScrollSpeed; float mOriginalY; // mY initially, used to restore scroller to original position after update
protected: protected:
string wordWrap(string sentence, float width); string wordWrap(string sentence, float width);
@@ -54,6 +54,6 @@ public:
VerticalTextScroller(int fontId, float x, float y, float width, float height, float scrollSpeed = 30, size_t _minimumItems = 1); VerticalTextScroller(int fontId, float x, float y, float width, float height, float scrollSpeed = 30, size_t _minimumItems = 1);
void Render(); void Render();
void Update(float dt); void Update(float dt);
void Add(string text);
}; };
#endif #endif

View File

@@ -39,6 +39,8 @@ string& trim(string &str);
string& ltrim(string &str); string& ltrim(string &str);
string& rtrim(string &str); string& rtrim(string &str);
std::string join(vector<string> &v, string delim = " ");
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems); std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems);
std::vector<std::string> split(const std::string &s, char delim); //splits a string with "delim" and returns a vector of strings. std::vector<std::string> split(const std::string &s, char delim); //splits a string with "delim" and returns a vector of strings.
std::string wordWrap(std::string s, int width); std::string wordWrap(std::string s, int width);

View File

@@ -19,6 +19,7 @@ namespace
const float kDescriptionHorizontalBoxPadding = 5; const float kDescriptionHorizontalBoxPadding = 5;
const float kDefaultFontScale = 1.0f; const float kDefaultFontScale = 1.0f;
const float kVerticalScrollSpeed = 7.0f
const int DETAILED_INFO_THRESHOLD = 20; const int DETAILED_INFO_THRESHOLD = 20;
} }
@@ -27,11 +28,7 @@ hgeParticleSystem* DeckMenu::stars = NULL;
// //
// For the additional info window, maximum characters per line is roughly 30 characters across. // For the additional info window, maximum characters per line is roughly 30 characters across.
// TODO: figure a way to get incoming text to wrap. // TODO:
//
// used fixed locations where the menu, title and descriptive text are located.
// * menu at (125, 60 )
// * descriptive information 125
// *** Need to make this configurable in a file somewhere to allow for class reuse // *** Need to make this configurable in a file somewhere to allow for class reuse
DeckMenu::DeckMenu(int id, JGuiListener* listener, int fontId, const string _title, const int& startIndex, bool showDetailsOverride) : DeckMenu::DeckMenu(int id, JGuiListener* listener, int fontId, const string _title, const int& startIndex, bool showDetailsOverride) :
@@ -72,7 +69,7 @@ JGuiController(id, listener), fontId(fontId), mShowDetailsScreen( showDetailsOve
float scrollerWidth = 200.0f; float scrollerWidth = 200.0f;
float scrollerHeight = 28.0f; float scrollerHeight = 28.0f;
mScroller = NEW VerticalTextScroller(Fonts::MAIN_FONT, 14, 235, scrollerWidth, 28.0f, 100); mScroller = NEW VerticalTextScroller(Fonts::MAIN_FONT, 14, 235, scrollerWidth, 28.0f, kVerticalScrollSpeed);
mAutoTranslate = true; mAutoTranslate = true;
maxItems = 7; maxItems = 7;
@@ -315,7 +312,7 @@ void DeckMenu::updateScroller()
{ {
ostringstream taskDescription; ostringstream taskDescription;
taskDescription << "[ " << setw(4) << (*it)->getReward() << " / " << (*it)->getExpiration() << " ] " taskDescription << "[ " << setw(4) << (*it)->getReward() << " / " << (*it)->getExpiration() << " ] "
<< (*it)->getDesc() << endl; << (*it)->getDesc() << endl << endl;
mScroller->Add(taskDescription.str()); mScroller->Add(taskDescription.str());
} }

View File

@@ -70,9 +70,9 @@ void DeckMenuItem::RenderWithOffset(float yOffset)
JTexture * tex = resources.RetrieveTexture("new.png"); JTexture * tex = resources.RetrieveTexture("new.png");
if (tex) if (tex)
{ {
JQuad * quad = resources.RetrieveQuad("new.png", 2, 2, tex->mWidth - 4, tex->mHeight - 4); //avoids weird rectangle aroudn the texture because of bilinear filtering JQuad * quad = resources.RetrieveQuad("new.png", 2, 2, tex->mWidth - 4, tex->mHeight - 4); //avoids weird rectangle aroudn the texture because of bilinear filtering
quad->SetHotSpot(quad->mWidth/2, quad->mHeight/2); quad->SetHotSpot(quad->mWidth/2, quad->mHeight/2);
float x = mX + min(ITEM_PX_WIDTH - quad->mWidth, mFont->GetStringWidth(menuItemString.c_str()))/2 + quad->mWidth/2; float x = mX + min(ITEM_PX_WIDTH - quad->mWidth, mFont->GetStringWidth(menuItemString.c_str()))/2 + quad->mWidth/2;
if (quad) JRenderer::GetInstance()->RenderQuad(quad, x , mY + yOffset + quad->mHeight/2, 0.5); if (quad) JRenderer::GetInstance()->RenderQuad(quad, x , mY + yOffset + quad->mHeight/2, 0.5);
} }
} }

View File

@@ -31,7 +31,8 @@ void TextScroller::setRandom(int mode)
void TextScroller::Add(string text) void TextScroller::Add(string text)
{ {
if (!strings.size()) mText = text; if (!strings.size())
mText = text;
strings.push_back(text); strings.push_back(text);
} }
@@ -85,50 +86,61 @@ ostream& TextScroller::toString(ostream& out) const
VerticalTextScroller::VerticalTextScroller(int fontId, float x, float y, float width, float height, float scrollSpeed, size_t numItemsShown) : VerticalTextScroller::VerticalTextScroller(int fontId, float x, float y, float width, float height, float scrollSpeed, size_t numItemsShown) :
TextScroller( fontId, x, y, width, scrollSpeed) TextScroller( fontId, x, y, width, scrollSpeed)
{ {
mHeight = height; mHeight = height;
mNbItemsShown = numItemsShown; mNbItemsShown = numItemsShown;
mVerticalScrollSpeed = 10.0f;
mMarginX = 0; mMarginX = 0;
mMarginY = 215;
mScrollerInitialized = false; mScrollerInitialized = false;
timer=0;
WFont *mFont = resources.GetWFont(fontId);
mOriginalY = mY;
mMarginY = mY - mFont->GetHeight();
Add("\n"); // initialize the scroller with a blank line
} }
void VerticalTextScroller::Add( string text )
{
strings.push_back( text );
string wrappedText = wordWrap(text, mWidth);
mText.append(wrappedText);
}
/*
Updates happen everytime the top line disappears from view.
The top line is then moved to the end of the file and the scrolling resumes where it left off
*/
void VerticalTextScroller::Update(float dt) void VerticalTextScroller::Update(float dt)
{ {
if (!strings.size()) return; if (!strings.size()) return;
WFont * mFont = resources.GetWFont(fontId);
ostringstream scrollerText;
// update the veritcal scrolling float currentYOffset = mScrollSpeed * dt;
if ( mScrollerInitialized )
{ if ( mY <= mMarginY ) // top line has disappeared
mY -= mVerticalScrollSpeed * dt; {
if ( mY < mMarginY ) timer = 0;
mY = mMarginY + 20; // now readjust mText
size_t nbLines = 1;
vector<string> displayText = split( mText, '\n');
vector<string> newDisplayText;
for ( size_t i = nbLines; i < displayText.size(); ++i )
newDisplayText.push_back( displayText[i] );
for ( size_t i = 0; i < nbLines; ++i )
newDisplayText.push_back( displayText[i] );
mText = join( newDisplayText, "\n" );
mY = mOriginalY;
} }
++timer;
// update the text mY -= currentYOffset;
if (timer == 0)
{
mScrollerInitialized = false;
size_t nbItemsToDisplay = (mNbItemsShown < strings.size() ? mNbItemsShown : strings.size());
for (size_t idx = 0; idx < nbItemsToDisplay; ++idx)
{
size_t index = (currentId + idx) % strings.size();
scrollerText << strings[index];
}
currentId++;
if (currentId >= strings.size())
currentId = 0;
mText = wordWrap(scrollerText.str(), mWidth);
mY = mMarginY + 20;
}
timer = ++timer % ((int) mScrollSpeed);
} }
void VerticalTextScroller::Render() void VerticalTextScroller::Render()
@@ -172,6 +184,6 @@ std::string VerticalTextScroller::wordWrap(std::string sentence, float width)
} }
if ( numLines * mFont->GetHeight() > mHeight ) if ( numLines * mFont->GetHeight() > mHeight )
mScrollerInitialized = true; mScrollerInitialized = true;
return retVal; return retVal;
} }

View File

@@ -218,6 +218,18 @@ std::vector<std::string> &split(const std::string &s, char delim, std::vector<st
return elems; return elems;
} }
std::string join( vector<string> &v, string delim)
{
std::string retVal;
for ( vector<string>::iterator it = v.begin(); it != v.end(); ++it )
{
retVal.append( *it );
retVal.append( delim );
}
return retVal;
}
std::vector<std::string> split(const std::string &s, char delim) std::vector<std::string> split(const std::string &s, char delim)
{ {
std::vector<std::string> elems; std::vector<std::string> elems;