moved word wrap function from Vertical Scroller into utils.
moved MTG specific functions out of utils.cpp into AllAbilities added word wrapping to descriptions while viewing deck information.
This commit is contained in:
@@ -5138,4 +5138,12 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// utility functions
|
||||||
|
|
||||||
|
void PopulateColorIndexVector( list<int>& colors, const string& colorsString, char delimiter = ',');
|
||||||
|
void PopulateAbilityIndexVector( list<int>& abilities, const string& abilitiesString, char delimiter = ',');
|
||||||
|
void PopulateSubtypesIndexVector( list<int>& subtypes, const string& subtypesString, char delimiter = ' ');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ class VerticalTextScroller:
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
size_t mNbItemsShown;
|
size_t mNbItemsShown;
|
||||||
bool mScrollerInitialized;
|
|
||||||
float mHeight; // maximum height availble for display
|
float mHeight; // maximum height availble for display
|
||||||
float mMarginX;
|
float mMarginX;
|
||||||
float mMarginY; // margin used to allow text to scroll off screen without
|
float mMarginY; // margin used to allow text to scroll off screen without
|
||||||
@@ -47,9 +46,6 @@ private:
|
|||||||
// for at least one line of text ( mY - line height of current font )
|
// for at least one line of text ( mY - line height of current font )
|
||||||
float mOriginalY; // mY initially, used to restore scroller to original position after update
|
float mOriginalY; // mY initially, used to restore scroller to original position after update
|
||||||
|
|
||||||
protected:
|
|
||||||
string wordWrap(string sentence, float width);
|
|
||||||
|
|
||||||
public:
|
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();
|
||||||
|
|||||||
@@ -43,12 +43,7 @@ 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, float width, int fontId);
|
||||||
|
|
||||||
void PopulateColorIndexVector( list<int>& colors, const string& colorsString, char delimiter = ',');
|
|
||||||
void PopulateAbilityIndexVector( list<int>& abilities, const string& abilitiesString, char delimiter = ',');
|
|
||||||
void PopulateSubtypesIndexVector( list<int>& subtypes, const string& subtypesString, char delimiter = ' ');
|
|
||||||
|
|
||||||
|
|
||||||
int loadRandValues(string s);
|
int loadRandValues(string s);
|
||||||
int filesize(const char * filename);
|
int filesize(const char * filename);
|
||||||
|
|||||||
@@ -1991,3 +1991,44 @@ AUpkeep::~AUpkeep()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// utility functions
|
||||||
|
|
||||||
|
// Given a delimited string of abilities, add the ones to the list that are "Basic" MTG abilities
|
||||||
|
void PopulateAbilityIndexVector( list<int>& abilities, const string& abilityStringList, char delimiter )
|
||||||
|
{
|
||||||
|
vector<string> abilitiesList = split( abilityStringList, delimiter);
|
||||||
|
for ( vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter)
|
||||||
|
{
|
||||||
|
int abilityIndex = Constants::GetBasicAbilityIndex( *iter );
|
||||||
|
|
||||||
|
if (abilityIndex != -1)
|
||||||
|
abilities.push_back( abilityIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PopulateColorIndexVector( list<int>& colors, const string& colorStringList, char delimiter )
|
||||||
|
{
|
||||||
|
vector<string> abilitiesList = split( colorStringList, delimiter);
|
||||||
|
for ( vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter)
|
||||||
|
{
|
||||||
|
for (int colorIndex = Constants::MTG_COLOR_ARTIFACT; colorIndex < Constants::MTG_NB_COLORS; ++colorIndex)
|
||||||
|
{
|
||||||
|
// if the text is not a basic ability but contains a valid color add it to the color vector
|
||||||
|
if ( (Constants::GetBasicAbilityIndex( *iter ) != -1) && ((*iter).find( Constants::MTGColorStrings[ colorIndex ] ) != string::npos) )
|
||||||
|
colors.push_back(colorIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopulateSubtypesIndexVector( list<int>& types, const string& subTypesStringList, char delimiter)
|
||||||
|
{
|
||||||
|
vector<string> subTypesList = split( subTypesStringList, delimiter);
|
||||||
|
for (vector<string>::iterator it = subTypesList.begin(); it != subTypesList.end(); ++it)
|
||||||
|
{
|
||||||
|
string subtype = *it;
|
||||||
|
size_t id = Subtypes::subtypesList->find( subtype );
|
||||||
|
if ( id != string::npos )
|
||||||
|
types.push_back(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ JGuiController(id, listener), fontId(fontId), mShowDetailsScreen( showDetailsOve
|
|||||||
descX = 260 + kDescriptionVerticalBoxPadding;
|
descX = 260 + kDescriptionVerticalBoxPadding;
|
||||||
descY = 100 + kDescriptionHorizontalBoxPadding;
|
descY = 100 + kDescriptionHorizontalBoxPadding;
|
||||||
descHeight = 145;
|
descHeight = 145;
|
||||||
descWidth = 220;
|
descWidth = 200;
|
||||||
|
|
||||||
detailedInfoBoxX = 400;
|
detailedInfoBoxX = 400;
|
||||||
detailedInfoBoxY = 235;
|
detailedInfoBoxY = 235;
|
||||||
@@ -211,7 +211,7 @@ void DeckMenu::Render()
|
|||||||
if (quad) renderer->RenderQuad(quad, avatarX, avatarY);
|
if (quad) renderer->RenderQuad(quad, avatarX, avatarY);
|
||||||
}
|
}
|
||||||
// fill in the description part of the screen
|
// fill in the description part of the screen
|
||||||
string text = currentMenuItem->desc;
|
string text = wordWrap(currentMenuItem->desc, descWidth, mainFont->mFontID );
|
||||||
mainFont->DrawString(text.c_str(), descX, descY);
|
mainFont->DrawString(text.c_str(), descX, descY);
|
||||||
mFont->SetColor(ARGB(255,255,255,255));
|
mFont->SetColor(ARGB(255,255,255,255));
|
||||||
|
|
||||||
|
|||||||
@@ -280,18 +280,12 @@ void GameStateDuel::ensureOpponentMenu()
|
|||||||
opponentMenu = NEW DeckMenu(DUEL_MENU_CHOOSE_OPPONENT, this, Fonts::OPTION_FONT, "Choose Opponent",
|
opponentMenu = NEW DeckMenu(DUEL_MENU_CHOOSE_OPPONENT, this, Fonts::OPTION_FONT, "Choose Opponent",
|
||||||
GameStateDuel::selectedAIDeckId, true);
|
GameStateDuel::selectedAIDeckId, true);
|
||||||
opponentMenu->Add(MENUITEM_RANDOM_AI, "Random");
|
opponentMenu->Add(MENUITEM_RANDOM_AI, "Random");
|
||||||
if (options[Options::EVILTWIN_MODE_UNLOCKED].number) opponentMenu->Add(MENUITEM_EVIL_TWIN, "Evil Twin", _(
|
if (options[Options::EVILTWIN_MODE_UNLOCKED].number) opponentMenu->Add(MENUITEM_EVIL_TWIN, "Evil Twin",
|
||||||
"Can you play against yourself?").c_str());
|
_("Can you defeat yourself?").c_str());
|
||||||
DeckManager * deckManager = DeckManager::GetInstance();
|
DeckManager * deckManager = DeckManager::GetInstance();
|
||||||
vector<DeckMetaData*> opponentDeckList;
|
vector<DeckMetaData*> opponentDeckList;
|
||||||
if(!options[Options::CHEATMODEAIDECK].number)
|
int nbUnlockedDecks = options[Options::CHEATMODEAIDECK].number ? 1000 : options[Options::AIDECKS_UNLOCKED].number;
|
||||||
{
|
opponentDeckList = fillDeckMenu(opponentMenu, JGE_GET_RES("ai/baka"), "ai_baka", mPlayers[0], nbUnlockedDecks);
|
||||||
opponentDeckList = fillDeckMenu(opponentMenu, JGE_GET_RES("ai/baka"), "ai_baka", mPlayers[0], options[Options::AIDECKS_UNLOCKED].number);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
opponentDeckList = fillDeckMenu(opponentMenu, JGE_GET_RES("ai/baka"), "ai_baka", mPlayers[0],1000);
|
|
||||||
}
|
|
||||||
deckManager->updateMetaDataList(&opponentDeckList, true);
|
deckManager->updateMetaDataList(&opponentDeckList, true);
|
||||||
opponentMenu->Add(MENUITEM_CANCEL, "Cancel", _("Choose a different player deck").c_str());
|
opponentMenu->Add(MENUITEM_CANCEL, "Cancel", _("Choose a different player deck").c_str());
|
||||||
opponentDeckList.clear();
|
opponentDeckList.clear();
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ TextScroller( fontId, x, y, width, scrollSpeed)
|
|||||||
mHeight = height;
|
mHeight = height;
|
||||||
mNbItemsShown = numItemsShown;
|
mNbItemsShown = numItemsShown;
|
||||||
mMarginX = 0;
|
mMarginX = 0;
|
||||||
mScrollerInitialized = false;
|
|
||||||
timer=0;
|
timer=0;
|
||||||
WFont *mFont = resources.GetWFont(fontId);
|
WFont *mFont = resources.GetWFont(fontId);
|
||||||
mOriginalY = mY;
|
mOriginalY = mY;
|
||||||
@@ -109,7 +108,7 @@ TextScroller( fontId, x, y, width, scrollSpeed)
|
|||||||
void VerticalTextScroller::Add( string text )
|
void VerticalTextScroller::Add( string text )
|
||||||
{
|
{
|
||||||
strings.push_back( text );
|
strings.push_back( text );
|
||||||
string wrappedText = wordWrap(text, mWidth);
|
string wrappedText = wordWrap(text, mWidth, fontId);
|
||||||
mText.append(wrappedText);
|
mText.append(wrappedText);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,47 +147,3 @@ void VerticalTextScroller::Render()
|
|||||||
WFont * mFont = resources.GetWFont(fontId);
|
WFont * mFont = resources.GetWFont(fontId);
|
||||||
mFont->DrawString(mText.c_str(), mX, mY);
|
mFont->DrawString(mText.c_str(), mX, mY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This is a customized word wrap based on pixel width. It tries it's best
|
|
||||||
// to wrap strings using spaces as delimiters.
|
|
||||||
// Not sure how this translates into non-english fonts.
|
|
||||||
std::string VerticalTextScroller::wordWrap(std::string sentence, float width)
|
|
||||||
{
|
|
||||||
WFont * mFont = resources.GetWFont(fontId);
|
|
||||||
float lineWidth = mFont->GetStringWidth( sentence.c_str() );
|
|
||||||
string retVal = sentence;
|
|
||||||
if ( lineWidth < width ) return sentence;
|
|
||||||
|
|
||||||
int numLines = 1;
|
|
||||||
int breakIdx = 0;
|
|
||||||
for( size_t idx = 0; idx < sentence.length(); idx ++ )
|
|
||||||
{
|
|
||||||
if ( sentence[idx] == ' ' )
|
|
||||||
{
|
|
||||||
string currentSentence = sentence.substr(breakIdx, idx - breakIdx);
|
|
||||||
float stringLength = mFont->GetStringWidth( currentSentence.c_str() );
|
|
||||||
if (stringLength >= width)
|
|
||||||
{
|
|
||||||
if ( stringLength > width )
|
|
||||||
{
|
|
||||||
while ( sentence[idx-1] != ' ' )
|
|
||||||
idx--;
|
|
||||||
}
|
|
||||||
retVal[idx-1] = '\n';
|
|
||||||
breakIdx = idx;
|
|
||||||
numLines++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( sentence[idx] == '\n' )
|
|
||||||
{
|
|
||||||
numLines++;
|
|
||||||
breakIdx = idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( numLines * mFont->GetHeight() > mHeight )
|
|
||||||
mScrollerInitialized = true;
|
|
||||||
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|||||||
+44
-67
@@ -3,6 +3,8 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "MTGDefinitions.h"
|
#include "MTGDefinitions.h"
|
||||||
#include "Subtypes.h"
|
#include "Subtypes.h"
|
||||||
|
#include "WResourceManager.h"
|
||||||
|
#include "WFont.h"
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
@@ -236,80 +238,55 @@ std::vector<std::string> split(const std::string &s, char delim)
|
|||||||
return split(s, delim, elems);
|
return split(s, delim, elems);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string wordWrap(std::string sentence, int width)
|
// This is a customized word wrap based on pixel width. It tries it's best
|
||||||
|
// to wrap strings using spaces as delimiters.
|
||||||
|
// Not sure how this translates into non-english fonts.
|
||||||
|
std::string wordWrap(std::string sentence, float width, int fontId)
|
||||||
{
|
{
|
||||||
std::string::iterator it = sentence.begin();
|
WFont * mFont = resources.GetWFont(fontId);
|
||||||
|
float lineWidth = mFont->GetStringWidth( sentence.c_str() );
|
||||||
|
string retVal = sentence;
|
||||||
|
if ( lineWidth < width ) return sentence;
|
||||||
|
|
||||||
//remember how long next word is
|
int numLines = 1;
|
||||||
int nextWordLength = 0;
|
int breakIdx = 0;
|
||||||
int distanceFromWidth = width;
|
for( size_t idx = 0; idx < sentence.length(); idx ++ )
|
||||||
|
|
||||||
while (it != sentence.end())
|
|
||||||
{
|
{
|
||||||
while (*it != ' ')
|
if ( sentence[idx] == ' ' )
|
||||||
{
|
{
|
||||||
nextWordLength++;
|
string currentSentence = sentence.substr(breakIdx, idx - breakIdx);
|
||||||
distanceFromWidth--;
|
float stringLength = mFont->GetStringWidth( currentSentence.c_str() );
|
||||||
|
if (stringLength >= width)
|
||||||
++it;
|
|
||||||
|
|
||||||
// check if done
|
|
||||||
if (it == sentence.end())
|
|
||||||
{
|
{
|
||||||
return sentence;
|
if ( stringLength > width )
|
||||||
|
{
|
||||||
|
while ( sentence[idx-1] != ' ' )
|
||||||
|
idx--;
|
||||||
|
}
|
||||||
|
retVal[idx-1] = '\n';
|
||||||
|
breakIdx = idx;
|
||||||
|
numLines++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( sentence[idx] == '\n' )
|
||||||
|
{
|
||||||
|
string currentSentence = sentence.substr(breakIdx, idx - breakIdx);
|
||||||
|
float stringLength = mFont->GetStringWidth( currentSentence.c_str() );
|
||||||
|
if (stringLength >= width)
|
||||||
|
{
|
||||||
|
if ( stringLength > width )
|
||||||
|
{
|
||||||
|
while ( sentence[idx-1] != ' ' )
|
||||||
|
idx--;
|
||||||
|
retVal[idx-1] = '\n';
|
||||||
|
}
|
||||||
|
numLines++;
|
||||||
|
}
|
||||||
|
breakIdx = idx;
|
||||||
|
numLines++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextWordLength > distanceFromWidth)
|
return retVal;
|
||||||
{
|
|
||||||
*it = '\n';
|
|
||||||
distanceFromWidth = width;
|
|
||||||
nextWordLength = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//skip the space
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sentence;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given a delimited string of abilities, add the ones to the list that are "Basic" MTG abilities
|
|
||||||
void PopulateAbilityIndexVector( list<int>& abilities, const string& abilityStringList, char delimiter )
|
|
||||||
{
|
|
||||||
vector<string> abilitiesList = split( abilityStringList, delimiter);
|
|
||||||
for ( vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter)
|
|
||||||
{
|
|
||||||
int abilityIndex = Constants::GetBasicAbilityIndex( *iter );
|
|
||||||
|
|
||||||
if (abilityIndex != -1)
|
|
||||||
abilities.push_back( abilityIndex );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PopulateColorIndexVector( list<int>& colors, const string& colorStringList, char delimiter )
|
|
||||||
{
|
|
||||||
vector<string> abilitiesList = split( colorStringList, delimiter);
|
|
||||||
for ( vector<string>::iterator iter = abilitiesList.begin(); iter != abilitiesList.end(); ++iter)
|
|
||||||
{
|
|
||||||
for (int colorIndex = Constants::MTG_COLOR_ARTIFACT; colorIndex < Constants::MTG_NB_COLORS; ++colorIndex)
|
|
||||||
{
|
|
||||||
// if the text is not a basic ability but contains a valid color add it to the color vector
|
|
||||||
if ( (Constants::GetBasicAbilityIndex( *iter ) != -1) && ((*iter).find( Constants::MTGColorStrings[ colorIndex ] ) != string::npos) )
|
|
||||||
colors.push_back(colorIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PopulateSubtypesIndexVector( list<int>& types, const string& subTypesStringList, char delimiter)
|
|
||||||
{
|
|
||||||
vector<string> subTypesList = split( subTypesStringList, delimiter);
|
|
||||||
for (vector<string>::iterator it = subTypesList.begin(); it != subTypesList.end(); ++it)
|
|
||||||
{
|
|
||||||
string subtype = *it;
|
|
||||||
size_t id = Subtypes::subtypesList->find( subtype );
|
|
||||||
if ( id != string::npos )
|
|
||||||
types.push_back(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user