J :
* 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:
@@ -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;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#ifndef _WGUI_H_
|
||||
#define _WGUI_H_
|
||||
#include <set>
|
||||
|
||||
class hgeDistortionMesh;
|
||||
class GameStateOptions;
|
||||
@@ -35,6 +36,12 @@ 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() {};
|
||||
|
||||
@@ -44,6 +51,8 @@ public:
|
||||
|
||||
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;};
|
||||
|
||||
@@ -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,6 +187,8 @@ 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);};
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,10 +471,13 @@ bool OptionKey::CheckUserInput(JButton key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static JButton btnList[] = {JGE_BTN_MENU, JGE_BTN_CTRL, JGE_BTN_RIGHT,
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -23,6 +25,9 @@ PIXEL_TYPE WGuiBase::getColor(int type){
|
||||
else
|
||||
return ARGB(255,255,255,255);
|
||||
}
|
||||
else
|
||||
if(hasFocus())
|
||||
return ARGB(150,200,200,200);
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user