661 lines
16 KiB
C++
661 lines
16 KiB
C++
#include "PrecompiledHeader.h"
|
|
|
|
#include "OptionItem.h"
|
|
#include "PlayerData.h"
|
|
#include "Translate.h"
|
|
#include "Subtypes.h"
|
|
#include "TranslateKeys.h"
|
|
#include "StyleManager.h"
|
|
#include "SimpleMenu.h"
|
|
|
|
//OptionItem
|
|
OptionItem::OptionItem(int _id, string _displayValue) :
|
|
WGuiItem(_displayValue)
|
|
{
|
|
id = _id;
|
|
mFocus = false;
|
|
}
|
|
|
|
//OptionInteger
|
|
void OptionInteger::Render()
|
|
{
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT));
|
|
mFont->DrawString(_(displayValue).c_str(), x + 2, y + 3);
|
|
char buf[512];
|
|
|
|
if (maxValue == 1)
|
|
{
|
|
if (value)
|
|
sprintf(buf, "%s", _("Yes").c_str());
|
|
else
|
|
sprintf(buf, "%s", _("No").c_str());
|
|
}
|
|
else
|
|
{
|
|
if (value == defValue && strDefault.size())
|
|
sprintf(buf, "%s", _(strDefault).c_str());
|
|
else
|
|
sprintf(buf, "%i", value);
|
|
}
|
|
mFont->DrawString(buf, width - 5, y + 3, JGETEXT_RIGHT);
|
|
}
|
|
|
|
OptionInteger::OptionInteger(int _id, string _displayValue, int _maxValue, int _increment, int _defV, string _sDef, int _minValue) :
|
|
OptionItem(_id, _displayValue)
|
|
{
|
|
defValue = _defV;
|
|
strDefault = _sDef;
|
|
maxValue = _maxValue;
|
|
minValue = _minValue;
|
|
increment = _increment;
|
|
value = ::options[id].number;
|
|
x = 0;
|
|
y = 0;
|
|
}
|
|
|
|
void OptionInteger::setData()
|
|
{
|
|
if (id != INVALID_OPTION)
|
|
options[id] = GameOption(value);
|
|
}
|
|
|
|
//Option Select
|
|
void OptionSelect::initSelections()
|
|
{
|
|
//Find currently active bit in the list.
|
|
for (size_t i = 0; i < selections.size(); ++i)
|
|
if (selections[i] == options[id].str)
|
|
value = i;
|
|
}
|
|
|
|
void OptionSelect::Entering(JButton key)
|
|
{
|
|
OptionItem::Entering(key);
|
|
prior_value = value;
|
|
}
|
|
|
|
void OptionSelect::Render()
|
|
{
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT));
|
|
mFont->DrawString(_(displayValue).c_str(), x, y + 2);
|
|
|
|
if (value < selections.size())
|
|
mFont->DrawString(_(selections[value]).c_str(), x + width - 10, y + 2, JGETEXT_RIGHT);
|
|
else
|
|
mFont->DrawString(_("Unset").c_str(), x + width - 10, y + 2, JGETEXT_RIGHT);
|
|
}
|
|
|
|
void OptionSelect::setData()
|
|
{
|
|
if (id == INVALID_OPTION)
|
|
return;
|
|
|
|
if (value < selections.size())
|
|
options[id] = GameOption(selections[value]);
|
|
}
|
|
bool OptionSelect::Selectable()
|
|
{
|
|
return (selections.size() > 1);
|
|
}
|
|
|
|
void OptionSelect::addSelection(string s)
|
|
{
|
|
selections.push_back(s);
|
|
}
|
|
|
|
//OptionProfile
|
|
const string OptionProfile::DIRTESTER = "collection.dat";
|
|
OptionProfile::OptionProfile(GameApp * _app, JGuiListener * jgl) :
|
|
OptionDirectory("profiles/", Options::ACTIVE_PROFILE, "Profile", DIRTESTER)
|
|
{
|
|
app = _app;
|
|
listener = jgl;
|
|
height = 60;
|
|
addSelection("Default");
|
|
sort(selections.begin(), selections.end());
|
|
mFocus = false;
|
|
initSelections();
|
|
populate();
|
|
}
|
|
;
|
|
|
|
void OptionProfile::initSelections()
|
|
{
|
|
OptionSelect::initSelections();
|
|
initialValue = value;
|
|
}
|
|
|
|
void OptionProfile::addSelection(string s)
|
|
{
|
|
OptionDirectory::addSelection(s);
|
|
|
|
//Check how many options... if 1, we're not selectable.
|
|
if (selections.size() > 1)
|
|
canSelect = true;
|
|
else
|
|
canSelect = false;
|
|
|
|
}
|
|
|
|
void OptionProfile::updateValue()
|
|
{
|
|
value++;
|
|
if (value > selections.size() - 1)
|
|
value = 0;
|
|
|
|
populate();
|
|
}
|
|
|
|
void OptionProfile::Reload()
|
|
{
|
|
OptionDirectory::Reload();
|
|
populate();
|
|
}
|
|
|
|
void OptionProfile::populate()
|
|
{
|
|
string temp = options[Options::ACTIVE_PROFILE].str;
|
|
if (value >= selections.size())
|
|
{ //TODO fail gracefully.
|
|
return;
|
|
}
|
|
options[Options::ACTIVE_PROFILE].str = selections[value];
|
|
PlayerData * pdata = NEW PlayerData(MTGCollection());
|
|
|
|
int unlocked = 0, sets = setlist.size();
|
|
std::string contents;
|
|
if (JFileSystem::GetInstance()->readIntoString(options.profileFile(PLAYER_SETTINGS), contents))
|
|
{
|
|
std::stringstream stream(contents);
|
|
std::string s;
|
|
while (std::getline(stream, s))
|
|
{
|
|
if (s.substr(0, 9) == "unlocked_")
|
|
unlocked++;
|
|
}
|
|
}
|
|
|
|
options[Options::ACTIVE_PROFILE] = temp;
|
|
|
|
char buf[512], format[512];
|
|
sprintf(format, "%s\n%s\n%s\n", _("Credits: %i").c_str(), _("Cards: %i").c_str(), _("Sets: %i (of %i)").c_str());
|
|
sprintf(buf, format, pdata->credits, pdata->collection->totalCards(), unlocked, sets);
|
|
preview = buf;
|
|
|
|
SAFE_DELETE(pdata);
|
|
}
|
|
|
|
void OptionProfile::Render()
|
|
{
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
mFont->SetScale(1);
|
|
int spacing = 2 + (int) mFont->GetHeight();
|
|
|
|
float pX, pY;
|
|
pX = x;
|
|
pY = y;
|
|
char buf[512];
|
|
if (selections[value] == "Default")
|
|
sprintf(buf, "player/avatar.jpg");
|
|
else
|
|
sprintf(buf, "profiles/%s/avatar.jpg", selections[value].c_str());
|
|
string filename = buf;
|
|
JQuadPtr avatar = WResourceManager::Instance()->RetrieveTempQuad(filename, TEXTURE_SUB_EXACT);
|
|
|
|
if (avatar)
|
|
{
|
|
renderer->RenderQuad(avatar.get(), x, pY);
|
|
pX += 40;
|
|
}
|
|
|
|
mFont->SetColor(getColor(WGuiColor::TEXT_HEADER));
|
|
mFont->DrawString(selections[value].c_str(), pX, pY + 2, JGETEXT_LEFT);
|
|
mFont->SetScale(0.8f);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT_BODY));
|
|
mFont->DrawString(preview.c_str(), pX, pY + spacing + 2, JGETEXT_LEFT);
|
|
mFont->SetScale(1.0f);
|
|
|
|
}
|
|
|
|
void OptionProfile::Entering(JButton)
|
|
{
|
|
mFocus = true;
|
|
initialValue = value;
|
|
}
|
|
|
|
void OptionProfile::confirmChange(bool confirmed)
|
|
{
|
|
if (initialValue >= selections.size())
|
|
return;
|
|
|
|
int result;
|
|
|
|
if (confirmed)
|
|
result = value;
|
|
else
|
|
result = initialValue;
|
|
|
|
options[Options::ACTIVE_PROFILE] = selections[result];
|
|
value = result;
|
|
|
|
populate();
|
|
if (listener && confirmed)
|
|
{
|
|
listener->ButtonPressed(-102, 5);
|
|
initialValue = value;
|
|
}
|
|
return;
|
|
}
|
|
|
|
//OptionThemeStyle
|
|
OptionThemeStyle::OptionThemeStyle(string _displayValue) :
|
|
OptionSelect(Options::GUI_STYLE, _displayValue)
|
|
{
|
|
Reload();
|
|
initSelections();
|
|
}
|
|
|
|
bool OptionThemeStyle::Visible()
|
|
{
|
|
return (selections.size() > 1);
|
|
}
|
|
|
|
void OptionThemeStyle::confirmChange(bool)
|
|
{
|
|
options.getStyleMan()->determineActive(NULL, NULL);
|
|
}
|
|
|
|
void OptionThemeStyle::Reload()
|
|
{
|
|
selections.clear();
|
|
addSelection("Dynamic");
|
|
map<string, WStyle*>::iterator it;
|
|
|
|
StyleManager * sm = options.getStyleMan();
|
|
for (it = sm->styles.begin(); it != sm->styles.end(); it++)
|
|
addSelection(it->first);
|
|
}
|
|
//OptionLanguage
|
|
OptionLanguage::OptionLanguage(string _displayValue) :
|
|
OptionSelect(Options::LANG, _displayValue)
|
|
{
|
|
Reload();
|
|
initSelections();
|
|
}
|
|
;
|
|
|
|
void OptionLanguage::setData()
|
|
{
|
|
if (id == INVALID_OPTION)
|
|
return;
|
|
|
|
if (value < selections.size())
|
|
{
|
|
options[id] = GameOption(actual_data[value]);
|
|
Translator::EndInstance();
|
|
Translator::GetInstance()->init();
|
|
Translator::GetInstance()->tempValues.clear();
|
|
}
|
|
}
|
|
|
|
void OptionLanguage::confirmChange(bool confirmed)
|
|
{
|
|
if (!confirmed)
|
|
value = prior_value;
|
|
else
|
|
{
|
|
setData();
|
|
if (Changed())
|
|
{
|
|
options[id] = GameOption(actual_data[value]);
|
|
Translator::EndInstance();
|
|
Translator::GetInstance()->init();
|
|
Translator::GetInstance()->tempValues.clear();
|
|
}
|
|
prior_value = value;
|
|
}
|
|
}
|
|
|
|
void OptionLanguage::Reload()
|
|
{
|
|
|
|
vector<string> langFiles = JFileSystem::GetInstance()->scanfolder("lang/");
|
|
for (size_t i = 0; i < langFiles.size(); ++i)
|
|
{
|
|
izfstream file;
|
|
string filePath = "lang/";
|
|
filePath.append(langFiles[i]);
|
|
if (! JFileSystem::GetInstance()->openForRead(file, filePath))
|
|
continue;
|
|
|
|
string s;
|
|
string lang;
|
|
|
|
if (std::getline(file, s))
|
|
{
|
|
if (!s.size())
|
|
{
|
|
lang = "";
|
|
}
|
|
else
|
|
{
|
|
if (s[s.size() - 1] == '\r')
|
|
s.erase(s.size() - 1); //Handle DOS files
|
|
size_t found = s.find("#LANG:");
|
|
if (found != 0)
|
|
lang = "";
|
|
else
|
|
lang = s.substr(6);
|
|
}
|
|
}
|
|
file.close();
|
|
|
|
if (lang.size())
|
|
{
|
|
string filen = langFiles[i];
|
|
addSelection(filen.substr(0, filen.size() - 4), lang);
|
|
}
|
|
}
|
|
initSelections();
|
|
}
|
|
|
|
void OptionLanguage::addSelection(string s, string show)
|
|
{
|
|
selections.push_back(show);
|
|
actual_data.push_back(s);
|
|
}
|
|
|
|
void OptionLanguage::initSelections()
|
|
{
|
|
//Find currently active bit in the list.
|
|
for (size_t i = 0; i < actual_data.size(); i++)
|
|
{
|
|
if (actual_data[i] == options[id].str)
|
|
value = i;
|
|
}
|
|
}
|
|
|
|
bool OptionLanguage::Visible()
|
|
{
|
|
if (selections.size() > 1)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool OptionLanguage::Selectable()
|
|
{
|
|
if (selections.size() > 1)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
//OptionDirectory
|
|
void OptionDirectory::Reload()
|
|
{
|
|
vector<string> subfolders = JFileSystem::GetInstance()->scanfolder(root);
|
|
for (size_t i = 0; i < subfolders.size(); ++i)
|
|
{
|
|
string filename = root + "/" + subfolders[i] + "/" + type;
|
|
if (!JFileSystem::GetInstance()->FileExists(filename))
|
|
continue;
|
|
if (find(selections.begin(), selections.end(), subfolders[i]) == selections.end())
|
|
addSelection(subfolders[i]);
|
|
}
|
|
initSelections();
|
|
}
|
|
|
|
OptionDirectory::OptionDirectory(string root, int id, string displayValue, string type) :
|
|
OptionSelect(id, displayValue), root(root), type(type)
|
|
{
|
|
vector<string> subfolders = JFileSystem::GetInstance()->scanfolder(root);
|
|
|
|
for (size_t i = 0; i < subfolders.size(); ++i)
|
|
{
|
|
string subfolder = subfolders[i].substr(0, subfolders[i].length());
|
|
if(subfolder[subfolders[i].length()-1] == '/')
|
|
subfolder = subfolders[i].substr(0, subfolders[i].length() - 1); //remove trailing "/"
|
|
vector<string> path;
|
|
path.push_back(root);
|
|
path.push_back(subfolder);
|
|
string filePath = buildFilePath(path, type);
|
|
if (JFileSystem::GetInstance()->FileExists(filePath))
|
|
addSelection(subfolder);
|
|
}
|
|
initSelections();
|
|
}
|
|
|
|
const string OptionTheme::DIRTESTER = "preview.png";
|
|
OptionTheme::OptionTheme(OptionThemeStyle * style) :
|
|
OptionDirectory("themes", Options::ACTIVE_THEME, "Current Theme", DIRTESTER)
|
|
{
|
|
addSelection("Default");
|
|
sort(selections.begin(), selections.end());
|
|
initSelections();
|
|
mFocus = false;
|
|
bChecked = false;
|
|
ts = style;
|
|
}
|
|
|
|
JQuadPtr OptionTheme::getImage()
|
|
{
|
|
char buf[512];
|
|
string val = selections[value];
|
|
if (val == "Default")
|
|
sprintf(buf, "graphics/preview.png");
|
|
else
|
|
sprintf(buf, "themes/%s/preview.png", val.c_str());
|
|
string filename = buf;
|
|
return WResourceManager::Instance()->RetrieveTempQuad(filename, TEXTURE_SUB_EXACT);
|
|
}
|
|
|
|
float OptionTheme::getHeight()
|
|
{
|
|
return 130;
|
|
}
|
|
|
|
void OptionTheme::updateValue()
|
|
{
|
|
OptionDirectory::updateValue();
|
|
bChecked = false;
|
|
}
|
|
|
|
void OptionTheme::Render()
|
|
{
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
char buf[512];
|
|
if (!bChecked)
|
|
{
|
|
author = "";
|
|
bChecked = true;
|
|
if (selections[value] == "Default")
|
|
sprintf(buf, "%s", "graphics/themeinfo.txt");
|
|
else
|
|
sprintf(buf, "themes/%s/themeinfo.txt", selections[value].c_str());
|
|
string contents;
|
|
if (JFileSystem::GetInstance()->readIntoString(buf, contents))
|
|
{
|
|
std::stringstream stream(contents);
|
|
string temp;
|
|
std::getline(stream, temp);
|
|
for (unsigned int x = 0; x < 17 && x < temp.size(); x++)
|
|
{
|
|
if (isprint(temp[x])) //Clear stuff that breaks mFont->DrawString, cuts to 16 chars.
|
|
author += temp[x];
|
|
}
|
|
}
|
|
}
|
|
sprintf(buf, _("Theme: %s").c_str(), selections[value].c_str());
|
|
|
|
JQuadPtr q = getImage();
|
|
if (q)
|
|
{
|
|
float scale = 128 / q->mHeight;
|
|
renderer->RenderQuad(q.get(), x, y, 0, scale, scale);
|
|
}
|
|
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT_HEADER));
|
|
mFont->DrawString(buf, x + 2, y + 2);
|
|
if (bChecked && author.size())
|
|
{
|
|
mFont->SetColor(getColor(WGuiColor::TEXT_BODY));
|
|
mFont->SetScale(0.8f);
|
|
float hi = mFont->GetHeight();
|
|
sprintf(buf, _("Artist: %s").c_str(), author.c_str());
|
|
mFont->DrawString(buf, x + 2, y + getHeight() - hi);
|
|
mFont->SetScale(1);
|
|
}
|
|
}
|
|
|
|
bool OptionTheme::Visible()
|
|
{
|
|
if (selections.size() <= 1)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void OptionTheme::confirmChange(bool confirmed)
|
|
{
|
|
bChecked = false;
|
|
if (!confirmed)
|
|
value = prior_value;
|
|
else
|
|
{
|
|
setData();
|
|
options.getStyleMan()->loadRules();
|
|
options.getStyleMan()->determineActive(NULL, NULL);
|
|
if (ts)
|
|
ts->Reload();
|
|
|
|
WResourceManager::Instance()->Refresh(); //Update images
|
|
prior_value = value;
|
|
}
|
|
}
|
|
|
|
OptionKey::OptionKey(GameStateOptions* g, LocalKeySym from, JButton to) :
|
|
WGuiItem(""), from(from), to(to), grabbed(false), g(g), btnMenu(NULL)
|
|
{
|
|
}
|
|
|
|
void OptionKey::Update(float dt)
|
|
{
|
|
if (btnMenu)
|
|
btnMenu->Update(dt);
|
|
}
|
|
void OptionKey::Render()
|
|
{
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT));
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
|
|
if (LOCAL_KEY_NONE == from)
|
|
{
|
|
string msg = _("New binding...");
|
|
mFont->DrawString(msg, (SCREEN_WIDTH - mFont->GetStringWidth(msg.c_str())) / 2, y + 2);
|
|
}
|
|
else
|
|
{
|
|
const KeyRep& rep = translateKey(from);
|
|
if (rep.second)
|
|
renderer->RenderQuad(rep.second, x + 4, y + 3, 0, 16.0f / rep.second->mHeight, 16.0f / rep.second->mHeight);
|
|
else
|
|
mFont->DrawString(rep.first, x + 4, y + 3, JGETEXT_LEFT);
|
|
const KeyRep& rep2 = translateKey(to);
|
|
if (rep2.second)
|
|
{
|
|
float ratio = 16.0f / rep2.second->mHeight;
|
|
renderer->RenderQuad(rep2.second, x + width - (ratio * rep2.second->mWidth) - 2, y + 3, 0, ratio, ratio);
|
|
}
|
|
else
|
|
mFont->DrawString(rep2.first, width - 4, y + 3, JGETEXT_RIGHT);
|
|
}
|
|
}
|
|
|
|
bool OptionKey::CheckUserInput(JButton key)
|
|
{
|
|
if (btnMenu)
|
|
return btnMenu->CheckUserInput(key);
|
|
if (JGE_BTN_OK == key)
|
|
{
|
|
grabbed = true;
|
|
g->GrabKeyboard(this);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static const JButton btnList[] =
|
|
{
|
|
JGE_BTN_MENU,
|
|
JGE_BTN_CTRL,
|
|
JGE_BTN_RIGHT,
|
|
JGE_BTN_LEFT,
|
|
JGE_BTN_UP,
|
|
JGE_BTN_DOWN,
|
|
JGE_BTN_OK,
|
|
JGE_BTN_CANCEL,
|
|
JGE_BTN_PRI,
|
|
JGE_BTN_SEC,
|
|
JGE_BTN_PREV,
|
|
JGE_BTN_NEXT,
|
|
#ifdef LINUX
|
|
JGE_BTN_FULLSCREEN,
|
|
#endif
|
|
JGE_BTN_NONE
|
|
};
|
|
|
|
void OptionKey::KeyPressed(LocalKeySym key)
|
|
{
|
|
from = key;
|
|
g->UngrabKeyboard(this);
|
|
grabbed = false;
|
|
|
|
btnMenu = NEW SimpleMenu(JGE::GetInstance(), WResourceManager::Instance(), 0, this, Fonts::MENU_FONT, 80, 10);
|
|
for (int i = sizeof(btnList) / sizeof(btnList[0]) - 1; i >= 0; --i)
|
|
{
|
|
const KeyRep& rep = translateKey(btnList[i]);
|
|
btnMenu->Add(i, rep.first.c_str());
|
|
}
|
|
}
|
|
bool OptionKey::isModal()
|
|
{
|
|
return grabbed || btnMenu;
|
|
}
|
|
|
|
void OptionKey::Overlay()
|
|
{
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
mFont->SetColor(ARGB(255, 0, 0, 0));
|
|
if (grabbed)
|
|
{
|
|
static const float x = 30, y = 45;
|
|
renderer->FillRoundRect(x, y, SCREEN_WIDTH - 2 * x, 50, 2, ARGB(200, 200, 200, 255));
|
|
string msg = _("Press a key to associate.");
|
|
mFont->DrawString(msg, (SCREEN_WIDTH - mFont->GetStringWidth(msg.c_str())) / 2, y + 20);
|
|
}
|
|
else if (btnMenu)
|
|
btnMenu->Render();
|
|
}
|
|
|
|
void OptionKey::ButtonPressed(int, int controlId)
|
|
{
|
|
to = btnList[controlId];
|
|
SAFE_DELETE(btnMenu);
|
|
btnMenu = NULL;
|
|
}
|
|
|
|
bool OptionKey::Visible()
|
|
{
|
|
return JGE_BTN_NONE != to || LOCAL_KEY_NONE == from || btnMenu != NULL;
|
|
}
|
|
|
|
bool OptionKey::Selectable()
|
|
{
|
|
return JGE_BTN_NONE != to || LOCAL_KEY_NONE == from || btnMenu != NULL;
|
|
}
|