* Add the confirmation screen for bindings.
  - Add support for asking confirmations before exiting the menu.
  - Add support for cancelling saving of options.
  - Add support for requesting focus when the parent allows to yield.
* Recenter most options' text.
* Change the background color of the selected options (else, there is
  no way of knowing where is the cursor when both option text and
  option value are icons).
* Change symbol names to their equivalent PSP icon use in wagic.
This commit is contained in:
jean.chalard
2010-02-28 12:36:09 +00:00
parent c2549af81d
commit 168154b52d
6 changed files with 296 additions and 50 deletions

View File

@@ -5,9 +5,6 @@
#include <JGui.h>
#include "../include/GameState.h"
#define SHOW_OPTIONS 1
#define SHOW_OPTIONS_MENU 2
class GameApp;
class WGuiTabMenu;
class SimpleMenu;
@@ -19,6 +16,11 @@ struct KeybGrabber {
class GameStateOptions: public GameState, public JGuiListener {
private:
enum {
SHOW_OPTIONS,
SHOW_OPTIONS_MENU,
SAVE
};
float timer;
bool mReload;
KeybGrabber* grabber;

View File

@@ -1,5 +1,6 @@
#ifndef _WGUI_H_
#define _WGUI_H_
#include <set>
class hgeDistortionMesh;
class GameStateOptions;
@@ -35,19 +36,27 @@ protected:
//Complete item interface
class WGuiBase: public JGuiListener {
public:
typedef enum {
CONFIRM_NEED, // Still needs confirmation
CONFIRM_OK, // Is okay (no need to confirm, or has been confirmed)
CONFIRM_CANCEL, // Is not okay, must cancel save
} CONFIRM_TYPE;
WGuiBase() {};
virtual ~WGuiBase() {};
virtual bool Selectable() {return true;};
virtual bool isModal() {return false;};
virtual bool Visible() {return true;};
virtual bool Changed() {return false;};
virtual void confirmChange(bool confirmed) {};
virtual CONFIRM_TYPE needsConfirm();
virtual bool yieldFocus();
virtual PIXEL_TYPE getColor(int type);
virtual float getMargin(int type) {return 4;};
virtual void Entering(JButton key)=0;
virtual void Entering(JButton key)=0;
virtual bool Leaving(JButton key)=0;
virtual void Update(float dt)=0;
@@ -84,6 +93,8 @@ public:
virtual void subBack(WGuiBase * item) {};
virtual bool CheckUserInput(JButton key) {return false;};
protected:
vector<WGuiBase*> items;
};
//This is our base class for concrete items.
@@ -176,7 +187,9 @@ public:
virtual bool Visible() {return it->Visible();};
virtual bool Changed() {return it->Changed();};
virtual void confirmChange(bool confirmed) {it->confirmChange(confirmed);};
virtual CONFIRM_TYPE needsConfirm() { return it->needsConfirm();};
virtual bool yieldFocus() {return it->yieldFocus();};
virtual void Entering(JButton key) {it->Entering(key);};
virtual bool Leaving(JButton key) {return it->Leaving(key);};
virtual void Update(float dt) {it->Update(dt);};
@@ -235,6 +248,7 @@ public:
WGuiSplit(WGuiBase* _left,WGuiBase* _right);
virtual ~WGuiSplit();
virtual bool yieldFocus();
virtual void Reload();
virtual void Overlay();
virtual void Underlay();
@@ -352,6 +366,7 @@ public:
virtual ~WGuiMenu();
WGuiMenu(JButton next, JButton prev, bool mDPad = false, WSyncable * syncme=NULL);
virtual bool yieldFocus();
virtual void Render();
virtual void Reload();
virtual void Update(float dt);
@@ -364,6 +379,7 @@ public:
virtual bool CheckUserInput(JButton key);
WGuiBase * Current();
virtual int getSelected() {return currentItem;};
virtual void setSelected(vector<WGuiBase*>::iterator& it);
virtual bool nextItem();
virtual bool prevItem();
virtual bool isModal();
@@ -376,7 +392,6 @@ protected:
virtual bool isButtonDir(JButton key, int dir); //For the DPad override.
JButton buttonNext, buttonPrev;
bool mDPad;
vector<WGuiBase*> items;
int currentItem;
JButton held;
WSyncable * sync;
@@ -494,9 +509,20 @@ class WGuiKeyBinder : public WGuiList {
virtual bool CheckUserInput(JButton);
virtual void setData();
virtual void Update(float);
virtual void Render();
virtual CONFIRM_TYPE needsConfirm();
virtual void ButtonPressed(int controllerId, int controlId);
virtual bool yieldFocus();
protected:
GameStateOptions* parent;
SimpleMenu* confirmMenu;
bool modal;
CONFIRM_TYPE confirmed;
LocalKeySym confirmingKey;
JButton confirmingButton;
set<LocalKeySym> confirmedKeys;
set<JButton> confirmedButtons;
string confirmationString;
};
#endif

View File

@@ -115,6 +115,24 @@ void GameStateOptions::Update(float dt)
}
else switch(mState){
default:
case SAVE:
switch (optionsTabs->needsConfirm())
{
case WGuiBase::CONFIRM_CANCEL:
mState = SHOW_OPTIONS;
break;
case WGuiBase::CONFIRM_OK:
optionsTabs->save();
JSoundSystem::GetInstance()->SetSfxVolume(options[Options::SFXVOLUME].number);
JSoundSystem::GetInstance()->SetMusicVolume(options[Options::MUSICVOLUME].number);
mParent->DoTransition(TRANSITION_FADE,GAME_STATE_MENU);
mState = SHOW_OPTIONS;
break;
case WGuiBase::CONFIRM_NEED:
optionsTabs->yieldFocus();
break;
}
// Note : No break here : must continue to continue updating the menu elements.
case SHOW_OPTIONS: {
JGE* j = JGE::GetInstance();
JButton key;
@@ -217,10 +235,9 @@ void GameStateOptions::ButtonPressed(int controllerId, int controlId)
if(controllerId == -102)
switch (controlId){
case 1:
optionsTabs->save();
mState = SAVE;
break;
//Set Audio volume
JSoundSystem::GetInstance()->SetSfxVolume(options[Options::SFXVOLUME].number);
JSoundSystem::GetInstance()->SetMusicVolume(options[Options::MUSICVOLUME].number);
case 2:
mParent->DoTransition(TRANSITION_FADE,GAME_STATE_MENU);
break;

View File

@@ -21,7 +21,7 @@ void OptionInteger::Render(){
mFont->SetColor(getColor(WGuiColor::TEXT));
JRenderer * renderer = JRenderer::GetInstance();
mFont->DrawString(_(displayValue).c_str(),x,y);
mFont->DrawString(_(displayValue).c_str(), x + 2, y + 3);
char buf[512];
if (maxValue == 1){
if (value)
@@ -34,7 +34,7 @@ void OptionInteger::Render(){
else
sprintf(buf, "%i", value);
}
mFont->DrawString(buf,width -10 ,y,JGETEXT_RIGHT);
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){
@@ -72,12 +72,12 @@ void OptionSelect::Render(){
mFont->SetColor(getColor(WGuiColor::TEXT));
JRenderer * renderer = JRenderer::GetInstance();
mFont->DrawString(_(displayValue).c_str(),x,y);
mFont->DrawString(_(displayValue).c_str(), x, y + 2);
if (value < selections.size())
mFont->DrawString(_(selections[value]).c_str(),x+width-10,y,JGETEXT_RIGHT);
mFont->DrawString(_(selections[value]).c_str(), x + width - 10, y + 2, JGETEXT_RIGHT);
else
mFont->DrawString(_("Unset").c_str(),x+width-10,y,JGETEXT_RIGHT);
mFont->DrawString(_("Unset").c_str(),x + width - 10, y + 2, JGETEXT_RIGHT);
}
void OptionSelect::setData(){
@@ -181,10 +181,10 @@ void OptionProfile::Render(){
}
mFont->SetColor(getColor(WGuiColor::TEXT_HEADER));
mFont->DrawString(selections[value].c_str(),pX,pY,JGETEXT_LEFT);
mFont->DrawString(selections[value].c_str(), pX, pY + 2, JGETEXT_LEFT);
mFont->SetScale(.8);
mFont->SetColor(getColor(WGuiColor::TEXT_BODY));
mFont->DrawString(preview.c_str(),pX,pY+spacing,JGETEXT_LEFT);
mFont->DrawString(preview.c_str(), pX, pY + spacing + 2, JGETEXT_LEFT);
mFont->SetScale(1);
}
@@ -401,13 +401,13 @@ void OptionTheme::Render(){
renderer->RenderQuad(q,x, y,0,scale,scale);
}
mFont->DrawString(buf,x,y);
mFont->DrawString(buf, x + 2, y + 2);
if(bChecked && author.size()){
mFont->SetColor(getColor(WGuiColor::TEXT_BODY));
mFont->SetScale(.8);
float hi = mFont->GetHeight();
sprintf(buf,_("Artist: %s").c_str(),author.c_str());
mFont->DrawString(buf,x,y+getHeight()-hi);
mFont->DrawString(buf, x + 2, y + getHeight() - hi);
mFont->SetScale(1);
}
}
@@ -447,14 +447,17 @@ void OptionKey::Render() {
{
const KeyRep& rep = translateKey(from);
if (rep.second)
renderer->RenderQuad(rep.second, x + 4, y + 2, 0, 16.0 / rep.second->mHeight, 16.0 / rep.second->mHeight);
renderer->RenderQuad(rep.second, x + 4, y + 3, 0, 16.0 / rep.second->mHeight, 16.0 / rep.second->mHeight);
else
mFont->DrawString(rep.first, x + 4, y + 2, JGETEXT_LEFT);
mFont->DrawString(rep.first, x + 4, y + 3, JGETEXT_LEFT);
const KeyRep& rep2 = translateKey(to);
if (rep2.second)
renderer->RenderQuad(rep2.second, x + 4, y + 2, 0, 16.0 / rep2.second->mHeight, 16.0 / rep2.second->mHeight);
{
float ratio = 16.0 / 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 + 2, JGETEXT_RIGHT);
mFont->DrawString(rep2.first, width - 4, y + 3, JGETEXT_RIGHT);
}
}
bool OptionKey::CheckUserInput(JButton key) {
@@ -468,11 +471,14 @@ bool OptionKey::CheckUserInput(JButton key) {
return false;
}
static 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,
JGE_BTN_NONE};
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);

View File

@@ -82,19 +82,19 @@ const KeyRep& translateKey(LocalKeySym key) {
{
if (fattable.end() == fattable.find(PSP_CTRL_SELECT))
{
fattable[PSP_CTRL_SELECT] = make_pair(_("Select"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_START] = make_pair(_("Start"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_UP] = make_pair(_("Up"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_RIGHT] = make_pair(_("Right"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_DOWN] = make_pair(_("Down"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_LEFT] = make_pair(_("Left"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_LTRIGGER] = make_pair(_("Left trigger"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_RTRIGGER] = make_pair(_("Right trigger"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_TRIANGLE] = make_pair(_("Triangle"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_CIRCLE] = make_pair(_("Circle"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_CROSS] = make_pair(_("Cross"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_SQUARE] = make_pair(_("Square"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_HOLD] = make_pair(_("Hold"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_SELECT] = make_pair(_("Select"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_START] = make_pair(_("Start"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_UP] = make_pair(_("Up"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_RIGHT] = make_pair(_("Right"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_DOWN] = make_pair(_("Down"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_LEFT] = make_pair(_("Left"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_LTRIGGER] = make_pair(_("Left trigger"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_RTRIGGER] = make_pair(_("Right trigger"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_TRIANGLE] = make_pair(_("Triangle"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_CIRCLE] = make_pair(_("Circle"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_CROSS] = make_pair(_("Cross"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_SQUARE] = make_pair(_("Square"), static_cast<JQuad*>(NULL));
fattable[PSP_CTRL_HOLD] = make_pair(_("Hold"), static_cast<JQuad*>(NULL));
}
else
{
@@ -128,6 +128,7 @@ const KeyRep& translateKey(LocalKeySym key) {
#endif
const KeyRep& translateKey(JButton key) {
/*
{
map<const JButton, KeyRep>::iterator res;
if ((res = slimtable.find(key)) != slimtable.end())
@@ -152,4 +153,52 @@ const KeyRep& translateKey(JButton key) {
slimtable[JGE_BTN_NEXT] = make_pair(_("Open hand/Next item"), static_cast<JQuad*>(NULL));
return slimtable[key];
*/
map<const JButton, KeyRep>::iterator res;
if ((res = slimtable.find(key)) == slimtable.end())
{
if (slimtable.end() == slimtable.find(JGE_BTN_CTRL))
{
slimtable[JGE_BTN_NONE] = make_pair(_("Delete this binding"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_CTRL] = make_pair(_("Select"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_MENU] = make_pair(_("Start"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_UP] = make_pair(_("Up"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_RIGHT] = make_pair(_("Right"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_DOWN] = make_pair(_("Down"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_LEFT] = make_pair(_("Left"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_PREV] = make_pair(_("Left trigger"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_NEXT] = make_pair(_("Right trigger"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_CANCEL] = make_pair(_("Triangle"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_OK] = make_pair(_("Circle"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_SEC] = make_pair(_("Cross"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_PRI] = make_pair(_("Square"), static_cast<JQuad*>(NULL));
slimtable[JGE_BTN_FULLSCREEN] = make_pair(_("Fullscreen"), static_cast<JQuad*>(NULL));
}
else
{
char* str = new char[11];
sprintf(str, "%d", key);
slimtable[key] = make_pair(str, static_cast<JQuad*>(static_cast<JQuad*>(NULL)));
}
res = slimtable.find(key);
}
KeyRep& k = res->second;
switch(key)
{
case JGE_BTN_CTRL : k.second = resources.RetrieveQuad("iconspsp.png", (float)2*32, 32, 64, 32, "PSP_CTRL_SELECT", RETRIEVE_NORMAL); break;
case JGE_BTN_MENU : k.second = resources.RetrieveQuad("iconspsp.png", (float)0*32, 32, 64, 32, "PSP_CTRL_START", RETRIEVE_NORMAL); break;
case JGE_BTN_UP : k.second = resources.RetrieveQuad("iconspsp.png", (float)0*32, 0, 32, 32, "PSP_CTRL_UP", RETRIEVE_NORMAL); break;
case JGE_BTN_RIGHT : k.second = resources.RetrieveQuad("iconspsp.png", (float)3*32, 0, 32, 32, "PSP_CTRL_RIGHT", RETRIEVE_NORMAL); break;
case JGE_BTN_DOWN : k.second = resources.RetrieveQuad("iconspsp.png", (float)1*32, 0, 32, 32, "PSP_CTRL_DOWN", RETRIEVE_NORMAL); break;
case JGE_BTN_LEFT : k.second = resources.RetrieveQuad("iconspsp.png", (float)2*32, 0, 32, 32, "PSP_CTRL_LEFT", RETRIEVE_NORMAL); break;
case JGE_BTN_PREV : k.second = resources.RetrieveQuad("iconspsp.png", (float)6*32, 32, 64, 32, "PSP_CTRL_LTRIGGER", RETRIEVE_NORMAL); break;
case JGE_BTN_NEXT : k.second = resources.RetrieveQuad("iconspsp.png", (float)8*32, 32, 64, 32, "PSP_CTRL_RTRIGGER", RETRIEVE_NORMAL); break;
case JGE_BTN_CANCEL : k.second = resources.RetrieveQuad("iconspsp.png", (float)5*32, 0, 32, 32, "PSP_CTRL_TRIANGLE", RETRIEVE_NORMAL); break;
case JGE_BTN_OK : k.second = resources.RetrieveQuad("iconspsp.png", (float)4*32, 0, 32, 32, "PSP_CTRL_CIRCLE", RETRIEVE_NORMAL); break;
case JGE_BTN_SEC : k.second = resources.RetrieveQuad("iconspsp.png", (float)7*32, 0, 32, 32, "PSP_CTRL_CROSS", RETRIEVE_NORMAL); break;
case JGE_BTN_PRI : k.second = resources.RetrieveQuad("iconspsp.png", (float)6*32, 0, 32, 32, "PSP_CTRL_SQUARE", RETRIEVE_NORMAL); break;
default: /* Unknown key : no icon */ ;
}
return k;
}

View File

@@ -3,6 +3,8 @@
#include "../include/PlayerData.h"
#include "../include/Translate.h"
#include "../include/Subtypes.h"
#include "../include/TranslateKeys.h"
#include <sstream>
#include <algorithm>
#include <hge/hgedistort.h>
@@ -24,7 +26,10 @@ PIXEL_TYPE WGuiBase::getColor(int type){
return ARGB(255,255,255,255);
}
else
return ARGB(150,50,50,50);
if(hasFocus())
return ARGB(150,200,200,200);
else
return ARGB(150,50,50,50);
}
return ARGB(150,50,50,50);
}
@@ -38,6 +43,21 @@ void WGuiBase::renderBack(WGuiBase * it){
else
subBack(it);
}
WGuiBase::CONFIRM_TYPE WGuiBase::needsConfirm() {
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); ++it) {
switch((*it)->needsConfirm()) {
case CONFIRM_NEED: return CONFIRM_NEED;
case CONFIRM_CANCEL: return CONFIRM_CANCEL;
case CONFIRM_OK: /* Nothing special : continue iteration */ ;
}
}
return CONFIRM_OK;
}
bool WGuiBase::yieldFocus() {
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); ++it)
if ((*it)->yieldFocus()) { return true; }
return false;
}
//WGuiItem
@@ -198,6 +218,23 @@ void WGuiMenu::subBack(WGuiBase * item){
renderer->FillRoundRect(item->getX(),item->getY(),item->getWidth()-4,item->getHeight()-2,2,item->getColor(WGuiColor::BACK));
}
void WGuiMenu::setSelected(vector<WGuiBase*>::iterator& it) {
int c = it - items.begin();
if (c != currentItem)
{
items[currentItem]->Leaving(JGE_BTN_NONE);
currentItem = c;
items[currentItem]->Entering(JGE_BTN_NONE);
}
}
bool WGuiMenu::yieldFocus() {
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); ++it)
if ((*it)->yieldFocus()) { setSelected(it); return true; }
return false;
}
//WGuiList
WGuiList::WGuiList(string name, WSyncable * syncme): WGuiMenu(JGE_BTN_DOWN, JGE_BTN_UP, false, syncme){
failMsg = "NO OPTIONS AVAILABLE";
@@ -367,10 +404,10 @@ void WDecoEnum::Render()
JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT);
mFont->SetColor(getColor(WGuiColor::TEXT));
JRenderer * renderer = JRenderer::GetInstance();
mFont->DrawString(_(getDisplay()).c_str(),getX(),getY());
mFont->DrawString(_(getDisplay()).c_str(), getX() + 2, getY() + 3);
OptionInteger* opt = dynamic_cast<OptionInteger*>(it);
if(opt)
mFont->DrawString(_(lookupVal(opt->value)).c_str(), getWidth() -10, getY(), JGETEXT_RIGHT);
mFont->DrawString(_(lookupVal(opt->value)).c_str(), getWidth() - 5, getY() + 3, JGETEXT_RIGHT);
}
WDecoEnum::WDecoEnum(WGuiBase * _it, EnumDefinition *_edef) : WGuiDeco(_it) {edef = _edef;}
@@ -692,6 +729,11 @@ void WGuiSplit::confirmChange(bool confirmed){
right->confirmChange(confirmed);
left->confirmChange(confirmed);
}
bool WGuiSplit::yieldFocus() {
if (right->yieldFocus()) { bRight = true; return true; }
if (left->yieldFocus()) { bRight = false; return true; }
return false;
}
//WGuiMenu
WGuiMenu::WGuiMenu(JButton next = JGE_BTN_RIGHT, JButton prev = JGE_BTN_LEFT, bool m, WSyncable * syncme): WGuiItem(""){
@@ -1767,7 +1809,7 @@ string WGuiFilterItem::getCode(){
return mCode;
}
WGuiKeyBinder::WGuiKeyBinder(string name, GameStateOptions* parent) : WGuiList(name), parent(parent), modal(false) {
WGuiKeyBinder::WGuiKeyBinder(string name, GameStateOptions* parent) : WGuiList(name), parent(parent), confirmMenu(NULL), modal(false), confirmed(CONFIRM_NEED), confirmingKey(LOCAL_KEY_NONE), confirmingButton(JGE_BTN_NONE), confirmationString("") {
JGE* j = JGE::GetInstance();
JGE::keybindings_it start = j->KeyBindings_begin(), end = j->KeyBindings_end();
@@ -1783,27 +1825,131 @@ void WGuiKeyBinder::Update(float dt) {
if (0 == currentItem) ++currentItem;
}
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); ++it) (*it)->Update(dt);
if (confirmMenu) confirmMenu->Update(dt);
}
bool WGuiKeyBinder::isModal() {
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); ++it)
if ((*it)->isModal()) return true;
return modal;
}
bool WGuiKeyBinder::CheckUserInput(JButton key)
{
bool WGuiKeyBinder::CheckUserInput(JButton key) {
if (confirmMenu)
return confirmMenu->CheckUserInput(key);
if (!items[currentItem]->CheckUserInput(key))
return WGuiList::CheckUserInput(key);
if (!items[currentItem]->Selectable())
nextItem();
return true;
}
void WGuiKeyBinder::setData(){
void WGuiKeyBinder::setData() {
JGE* j = JGE::GetInstance();
j->ClearBindings();
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); ++it) {
OptionKey* o = dynamic_cast<OptionKey*>(*it);
OptionKey* o = static_cast<OptionKey*>(*it);
if (o && LOCAL_KEY_NONE != o->from && JGE_BTN_NONE != o->to)
j->BindKey(o->from, o->to);
}
j->ResetInput();
}
static const JButton btnToCheck[] = {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 };
#define C(o) (static_cast<OptionKey*>(o))
WGuiBase::CONFIRM_TYPE WGuiKeyBinder::needsConfirm() {
if (CONFIRM_CANCEL == confirmed) { confirmedKeys.clear(); confirmedButtons.clear(); confirmed = CONFIRM_NEED; return CONFIRM_CANCEL; }
if (confirmMenu) return CONFIRM_NEED;
// Check whether any key is bound to two functions.
confirmingKey = LOCAL_KEY_NONE;
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); ++it) {
if (!(*it)->Visible()) continue;
vector<JButton> boundFunctionsList;
for (vector<WGuiBase*>::iterator jt = it + 1; jt != items.end(); ++jt) {
if (!(*jt)->Visible()) continue;
if (C(*it)->from == C(*jt)->from)
if (confirmedKeys.end() == find(confirmedKeys.begin(), confirmedKeys.end(), C(*it)->from)) {
confirmingKey = C(*it)->from;
if (boundFunctionsList.empty()) boundFunctionsList.push_back(C(*it)->to);
boundFunctionsList.push_back(C(*jt)->to);
}
}
if (LOCAL_KEY_NONE != confirmingKey) {
// There is a conflict. Generate the error message...
char s[1024];
snprintf(s, 1024, _("Warning : the %s key is bound to\n%i different functions:").c_str(), translateKey(confirmingKey).first.c_str(), boundFunctionsList.size());
stringstream ss;
ss << s << "\n";
vector<JButton>::iterator jt = boundFunctionsList.begin();
ss << translateKey(*jt).first.c_str();
for (++jt; jt != boundFunctionsList.end(); ++jt) ss << ", " << translateKey(*jt).first.c_str();
confirmationString = ss.str();
// Then create the menu.
confirmMenu = NEW SimpleMenu(0, this, Constants::MENU_FONT, 40, 130, "Conflict");
confirmMenu->Add(1, _("Cancel and return to the options menu").c_str());
confirmMenu->Add(2, _("This is okay, validate and save").c_str());
return CONFIRM_NEED;
}
}
// Check whether any button has no key associated to it.
confirmingButton = JGE_BTN_NONE;
for (signed int i = (sizeof(btnToCheck) / sizeof(btnToCheck[0])) - 1; i >= 0; --i) {
if (confirmedButtons.end() != find(confirmedButtons.begin(), confirmedButtons.end(), btnToCheck[i])) continue;
bool found = false;
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); ++it)
if (btnToCheck[i] == C(*it)->to) { found = true; break; }
if (found) continue;
char s[1024];
snprintf(s, 1024, _("Warning : no key is associated to\nthe %s function.\nThis may make the game unusable.").c_str(), translateKey(btnToCheck[i]).first.c_str());
confirmationString = s;
confirmingButton = btnToCheck[i];
confirmMenu = NEW SimpleMenu(1, this, Constants::MENU_FONT, 40, 130, "Binding missing");
confirmMenu->Add(1, _("Cancel and return to the options menu").c_str());
confirmMenu->Add(2, _("This is okay, validate and save").c_str());
return CONFIRM_NEED;
}
return CONFIRM_OK;
}
void WGuiKeyBinder::ButtonPressed(int controllerId, int controlId) {
if (2 == controlId)
switch(controllerId) {
case 0: confirmedKeys.insert(confirmingKey); break;
case 1: confirmedButtons.insert(confirmingButton); break;
}
else
confirmed = CONFIRM_CANCEL;
SAFE_DELETE(confirmMenu);
confirmMenu = NULL;
}
void WGuiKeyBinder::Render() {
WGuiList::Render();
if (confirmMenu) {
JRenderer * renderer = JRenderer::GetInstance();
JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT);
mFont->SetColor(ARGB(255, 255, 0, 0));
renderer->FillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, ARGB(230, 255, 240, 240));
size_t pos = 0;
u32 y = 20;
do {
size_t t = confirmationString.find_first_of("\n", pos);
string s = confirmationString.substr(pos, t - pos);
pos = (string::npos == t) ? t : t + 1;
mFont->DrawString(s, SCREEN_WIDTH / 2, y, JGETEXT_CENTER);
y += 20;
} while (pos != string::npos);
confirmMenu->Render();
}
}
bool WGuiKeyBinder::yieldFocus() {
return true;
}