You get a random legendary creature and get a 99 cards deck at random in the commander colors. Some limitations by the engine makes you only get cards based on the mana cost of the card, not the full color identity. Also sometimes you get fewer than 99 cards. Possible that you are getting repeated cards and end up with less than the desired 99? Special rarity no longer shows basic land types.
2537 lines
70 KiB
C++
2537 lines
70 KiB
C++
#include "PrecompiledHeader.h"
|
|
|
|
#include "OptionItem.h"
|
|
#include "PlayerData.h"
|
|
#include "Translate.h"
|
|
#include "Subtypes.h"
|
|
#include "TranslateKeys.h"
|
|
#include <hge/hgedistort.h>
|
|
#include "SimpleMenu.h"
|
|
#include "Pos.h"
|
|
#include "CardGui.h"
|
|
|
|
/**
|
|
Provides an interface to retrieve some standardized colors. The idea here is that a child of WGuiBase
|
|
could override, for example, the color of the background based on whether or notit is highlighted
|
|
(as WGuiButton does), or be given a particular styling with the WDecoStyled decorator.
|
|
*/
|
|
PIXEL_TYPE WGuiBase::getColor(int type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case WGuiColor::TEXT_BODY:
|
|
case WGuiColor::SCROLLBUTTON:
|
|
return ARGB(255,255,255,255);
|
|
case WGuiColor::SCROLLBAR:
|
|
return ARGB(150,50,50,50);
|
|
case WGuiColor::BACK_HEADER:
|
|
return ARGB(150,80,80,80);
|
|
default:
|
|
if (type < WGuiColor::BACK)
|
|
{
|
|
if (hasFocus())
|
|
return ARGB(255,255,255,0);
|
|
else
|
|
return ARGB(255,255,255,255);
|
|
}
|
|
else if (hasFocus())
|
|
return ARGB(150,200,200,200);
|
|
else
|
|
return ARGB(150,50,50,50);
|
|
}
|
|
return ARGB(150,50,50,50);
|
|
}
|
|
|
|
/**
|
|
Renders the backdrop of a WGui item.
|
|
Meant to be overriden in subclasses that require a unique backdrop.
|
|
*/
|
|
void WGuiBase::renderBack(WGuiBase * it)
|
|
{
|
|
if (!it) return;
|
|
WDecoStyled * styled = dynamic_cast<WDecoStyled*> (it);
|
|
if (styled)
|
|
styled->renderBack(styled->getDecorated());
|
|
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
|
|
void WGuiItem::Entering(JButton)
|
|
{
|
|
mFocus = true;
|
|
}
|
|
float WGuiItem::minWidth()
|
|
{
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
return mFont->GetStringWidth(_(displayValue).c_str()) + 4;
|
|
}
|
|
float WGuiItem::minHeight()
|
|
{
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
return mFont->GetHeight();
|
|
}
|
|
|
|
bool WGuiItem::Leaving(JButton)
|
|
{
|
|
mFocus = false;
|
|
return true;
|
|
}
|
|
|
|
void WGuiItem::Render()
|
|
{
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
DWORD oldcolor = mFont->GetColor();
|
|
mFont->SetColor(getColor(WGuiColor::TEXT));
|
|
float fH = (height - mFont->GetHeight()) / 2;
|
|
string trans = _(displayValue);
|
|
float fW = mFont->GetStringWidth(trans.c_str());
|
|
float boxW = getWidth();
|
|
float oldS = mFont->GetScale();
|
|
if (fW > boxW)
|
|
{
|
|
mFont->SetScale(boxW / fW);
|
|
}
|
|
mFont->DrawString(trans, x + (width / 2), y + fH, JGETEXT_CENTER);
|
|
mFont->SetScale(oldS);
|
|
mFont->SetColor(oldcolor);
|
|
}
|
|
|
|
WGuiItem::WGuiItem(string _display, u8 _mF)
|
|
{
|
|
mFlags = _mF;
|
|
displayValue = _display;
|
|
mFocus = false;
|
|
width = SCREEN_WIDTH;
|
|
height = 20;
|
|
x = 0;
|
|
y = 0;
|
|
}
|
|
|
|
string WGuiItem::_(string input)
|
|
{
|
|
if (mFlags & WGuiItem::NO_TRANSLATE) return input;
|
|
return ::_(input);
|
|
}
|
|
bool WGuiItem::CheckUserInput(JButton key)
|
|
{
|
|
if (mFocus && key == JGE_BTN_OK)
|
|
{
|
|
updateValue();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//WDecoStyled
|
|
void WDecoStyled::subBack(WGuiBase * item)
|
|
{
|
|
if (!item) return;
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
if (mStyle & DS_STYLE_BACKLESS)
|
|
return;
|
|
//TODO: if(mStyle & DS_STYLE_EDGED) Draw the edged box ala SimpleMenu
|
|
else
|
|
{ //Draw standard style
|
|
WGuiSplit * split = dynamic_cast<WGuiSplit*> (item);
|
|
if (split && split->left->Visible() && split->right->Visible())
|
|
{
|
|
if (split->left) renderer->FillRoundRect(split->left->getX() - 2, split->getY() - 2, split->left->getWidth() - 6,
|
|
split->getHeight(), 2, split->left->getColor(WGuiColor::BACK));
|
|
if (split->right) renderer->FillRoundRect(split->right->getX() - 2, split->getY() - 2, split->right->getWidth(),
|
|
split->getHeight(), 2, split->right->getColor(WGuiColor::BACK));
|
|
}
|
|
else
|
|
{
|
|
renderer->FillRoundRect(item->getX() - 2, item->getY() - 2, item->getWidth(), item->getHeight(), 2, getColor(
|
|
WGuiColor::BACK));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
PIXEL_TYPE WDecoStyled::getColor(int type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case WGuiColor::BACK:
|
|
case WGuiColor::BACK_HEADER:
|
|
if (mStyle & DS_COLOR_DARK)
|
|
return ARGB(150,35,35,35);
|
|
else if (mStyle & DS_COLOR_BRIGHT)
|
|
return ARGB(150,80,80,80);
|
|
else if (mStyle & DS_STYLE_ALERT)
|
|
return ARGB(150,120,80,80);
|
|
else
|
|
return ARGB(150,50,50,50);
|
|
default:
|
|
return WGuiBase::getColor(type);
|
|
}
|
|
return ARGB(150,50,50,50);
|
|
}
|
|
|
|
//WGuiHeader
|
|
void WGuiHeader::Render()
|
|
{
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
// save the current scaling factor. We don't want the lists to change font size these lists should stay the same no matter what
|
|
float currentScale = mFont->GetScale();
|
|
mFont->SetScale(SCALE_NORMAL);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT));
|
|
mFont->DrawString(_(displayValue).c_str(), x + width / 2, y, JGETEXT_CENTER);
|
|
mFont->SetScale(currentScale);
|
|
}
|
|
|
|
bool WGuiMenu::Leaving(JButton key)
|
|
{
|
|
int nbitems = (int) items.size();
|
|
if (key == buttonNext && currentItem < nbitems - 1)
|
|
return false;
|
|
else if (key == buttonPrev && currentItem > 0) return false;
|
|
|
|
if (currentItem >= 0 && currentItem < nbitems) if (!items[currentItem]->Leaving(key)) return false;
|
|
|
|
mFocus = false;
|
|
return true;
|
|
}
|
|
void WGuiMenu::Entering(JButton key)
|
|
{
|
|
mFocus = true;
|
|
|
|
//Try to force a selectable option.
|
|
if (currentItem == -1)
|
|
{
|
|
for (size_t i = 0; i < items.size(); i++)
|
|
{
|
|
if (items[i]->Selectable())
|
|
{
|
|
currentItem = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (currentItem >= 0 && currentItem < (int) items.size()) items[currentItem]->Entering(key);
|
|
return;
|
|
}
|
|
|
|
void WGuiMenu::subBack(WGuiBase * item)
|
|
{
|
|
if (!item) return;
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
|
|
WGuiSplit * split = dynamic_cast<WGuiSplit*> (item);
|
|
if (split && split->left->Visible() && split->right->Visible())
|
|
{
|
|
if (split->left) subBack(split->left);//renderer->FillRoundRect(split->left->getX()-2,split->getY()-2,split->left->getWidth()-6,split->getHeight(),2,split->left->getColor(WGuiColor::BACK));
|
|
if (split->right) subBack(split->right);//renderer->FillRoundRect(split->right->getX()-2,split->getY()-2,split->right->getWidth(),split->getHeight(),2,split->right->getColor(WGuiColor::BACK));
|
|
}
|
|
else
|
|
{
|
|
renderer->FillRoundRect(item->getX(), item->getY(), item->getWidth() - 4, item->getHeight() - 2, 1, item->getColor(
|
|
WGuiColor::BACK));
|
|
//inner border
|
|
renderer->DrawRoundRect(item->getX(), item->getY(), item->getWidth() - 4, item->getHeight() - 2, 1, ARGB(255,89,89,89));
|
|
//outer border
|
|
//renderer->DrawRect(item->getX()-1.5f, item->getY()-1, item->getWidth()+1, item->getHeight() +2, ARGB(80,240,240,240));
|
|
}
|
|
|
|
}
|
|
|
|
void WGuiMenu::setSelected(int newItem)
|
|
{
|
|
if (newItem != currentItem)
|
|
{
|
|
items[currentItem]->Leaving(JGE_BTN_NONE);
|
|
currentItem = newItem;
|
|
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), startWindow(-1), endWindow(-1)
|
|
{
|
|
failMsg = "NO OPTIONS AVAILABLE";
|
|
width = SCREEN_WIDTH - 10;
|
|
height = SCREEN_HEIGHT - 10;
|
|
y = 5;
|
|
x = 5;
|
|
mFocus = false;
|
|
sync = syncme;
|
|
displayValue = name;
|
|
}
|
|
void WGuiList::confirmChange(bool confirmed)
|
|
{
|
|
for (size_t x = 0; x < items.size(); x++)
|
|
{
|
|
if (!items[x]) continue;
|
|
items[x]->confirmChange(confirmed);
|
|
}
|
|
}
|
|
void WGuiList::Render()
|
|
{
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
int listHeight = 40;
|
|
int listSelectable = 0;
|
|
int adjustedCurrent = 0;
|
|
int start = 0, nowPos = 0, vHeight = 0;
|
|
int nbitems = (int) items.size();
|
|
|
|
//List is empty.
|
|
if (!items.size() && failMsg != "")
|
|
{
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
// save the current scaling factor. We don't want the lists to change font size these lists should stay the same no matter what
|
|
float fontScaleFactor = mFont->GetScale();
|
|
mFont->SetScale(SCALE_NORMAL);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT_FAIL));
|
|
mFont->DrawString(_(failMsg).c_str(), x + width / 2, y, JGETEXT_RIGHT);
|
|
mFont->SetScale(fontScaleFactor);
|
|
return;
|
|
}
|
|
|
|
//Force a selectable option.
|
|
if (currentItem == -1)
|
|
{
|
|
for (int i = 0; i < nbitems; i++)
|
|
{
|
|
if (items[i]->Selectable())
|
|
{
|
|
currentItem = i;
|
|
if (hasFocus()) items[currentItem]->Entering(JGE_BTN_NONE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//Find out how large our list is, with all items and margin.
|
|
for (int pos = 0; pos < nbitems; pos++)
|
|
{
|
|
listHeight += static_cast<int> (items[pos]->getHeight() + 1); //What does the +1 do exactly ?
|
|
if (items[pos]->Selectable())
|
|
{
|
|
listSelectable++;
|
|
if (pos < currentItem) adjustedCurrent++;
|
|
}
|
|
}
|
|
|
|
//Always fill screen
|
|
if (listHeight > SCREEN_HEIGHT)
|
|
{
|
|
for (start = currentItem; start > 0; start--)
|
|
{
|
|
if (!items[start]->Visible()) continue;
|
|
|
|
vHeight += static_cast<int> (items[start]->getHeight() + 5);
|
|
if (vHeight >= (SCREEN_HEIGHT - 60) / 2) break;
|
|
}
|
|
vHeight = 0;
|
|
if (start >= 0) for (nowPos = nbitems; nowPos > 1; nowPos--)
|
|
{
|
|
if (!items[start]->Visible()) continue;
|
|
vHeight += static_cast<int> (items[nowPos - 1]->getHeight() + 5);
|
|
}
|
|
|
|
if (vHeight <= SCREEN_HEIGHT - 40 && nowPos < start) start = nowPos;
|
|
}
|
|
|
|
vHeight = 0;
|
|
nowPos = 0;
|
|
|
|
//Render items.
|
|
if (start >= 0)
|
|
{
|
|
int pos;
|
|
//Render current underlay.
|
|
if (currentItem >= 0 && currentItem < nbitems && items[currentItem]->Visible()) items[currentItem]->Underlay();
|
|
|
|
for (pos = 0; pos < nbitems; pos++)
|
|
{
|
|
if (!items[pos]->Visible()) continue;
|
|
|
|
if (pos < start)
|
|
{
|
|
vHeight += static_cast<int> (items[pos]->getHeight() + 5);
|
|
continue;
|
|
}
|
|
|
|
items[pos]->setY(y + nowPos);
|
|
items[pos]->setX(x);
|
|
if (listHeight > SCREEN_HEIGHT && listSelectable > 1)
|
|
items[pos]->setWidth(width - 10);
|
|
else
|
|
items[pos]->setWidth(width);
|
|
nowPos += static_cast<int> (items[pos]->getHeight() + 5);
|
|
renderBack(items[pos]);
|
|
items[pos]->Render();
|
|
if (nowPos > SCREEN_HEIGHT) //Stop displaying things once we reach the bottom of the screen.
|
|
break;
|
|
}
|
|
|
|
startWindow = start;
|
|
endWindow = pos;
|
|
|
|
//Draw scrollbar
|
|
if (listHeight > SCREEN_HEIGHT && listSelectable > 1)
|
|
{
|
|
float barPosition = static_cast<float> (y - 5 + ((float) adjustedCurrent / listSelectable) * (SCREEN_HEIGHT - y));
|
|
float barLength = static_cast<float> ((SCREEN_HEIGHT - y) / listSelectable);
|
|
if (barLength < 4) barLength = 4;
|
|
renderer->FillRect(x + width - 2, y - 1, 2, SCREEN_HEIGHT - y, getColor(WGuiColor::SCROLLBAR));
|
|
renderer->FillRoundRect(x + width - 5, barPosition, 5, barLength, 1, getColor(WGuiColor::SCROLLBUTTON));
|
|
}
|
|
|
|
//Render current overlay.
|
|
if (currentItem >= 0 && currentItem < nbitems && items[currentItem]->Visible()) items[currentItem]->Overlay();
|
|
}
|
|
}
|
|
|
|
void WGuiList::setData()
|
|
{
|
|
for (size_t i = 0; i < items.size(); i++)
|
|
{
|
|
items[i]->setData();
|
|
}
|
|
}
|
|
|
|
void WGuiList::ButtonPressed(int controllerId, int controlId)
|
|
{
|
|
WGuiBase * it;
|
|
|
|
if (!(it = Current())) return;
|
|
|
|
it->ButtonPressed(controllerId, controlId);
|
|
}
|
|
|
|
bool WGuiList::CheckUserInput(JButton key)
|
|
{
|
|
JGE * mEngine = JGE::GetInstance();
|
|
int i, j;
|
|
|
|
if ((key == JGE_BTN_OK) && mEngine->GetLeftClickCoordinates(i, j))
|
|
{ // a dude clicked somwhere, we're gonna select the closest object from where he clicked
|
|
int n = currentItem;
|
|
unsigned int distance2;
|
|
unsigned int minDistance2 = -1;
|
|
int begin = (startWindow == -1) ? 0 : startWindow;
|
|
int end = (endWindow == -1) ? items.size() : endWindow;
|
|
for(int k = begin; k < end; k++)
|
|
{
|
|
WGuiBase* pItem = (items[k]);
|
|
distance2 = static_cast<unsigned int>((pItem->getY() - j) * (pItem->getY() - j) + (pItem->getX() - i) * (pItem->getX() - i));
|
|
if (distance2 < minDistance2 && pItem->Selectable())
|
|
{
|
|
minDistance2 = distance2;
|
|
n = k;
|
|
}
|
|
}
|
|
|
|
if (n != currentItem && items[n]->Selectable())
|
|
{
|
|
setSelected(n);
|
|
mEngine->LeftClickedProcessed();
|
|
if (sync) syncMove();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// mEngine->LeftClickedProcessed();
|
|
return WGuiMenu::CheckUserInput(key);
|
|
}
|
|
|
|
|
|
string WDecoEnum::lookupVal(int value)
|
|
{
|
|
|
|
if (edef == NULL)
|
|
{
|
|
int id = getId();
|
|
if (id != INVALID_ID)
|
|
{
|
|
GameOptionEnum * goEnum = dynamic_cast<GameOptionEnum*> (options.get(getId()));
|
|
if (goEnum) edef = goEnum->def;
|
|
}
|
|
}
|
|
|
|
if (edef)
|
|
{
|
|
int idx = edef->findIndex(value);
|
|
if (idx != INVALID_ID) return edef->values[idx].second;
|
|
}
|
|
|
|
char buf[32];
|
|
sprintf(buf, "%d", value);
|
|
return buf;
|
|
}
|
|
|
|
void WDecoEnum::Render()
|
|
{
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT));
|
|
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() - 5, getY() + 3, JGETEXT_RIGHT);
|
|
}
|
|
|
|
WDecoEnum::WDecoEnum(WGuiBase * _it, EnumDefinition *_edef) :
|
|
WGuiDeco(_it)
|
|
{
|
|
edef = _edef;
|
|
}
|
|
//WDecoCheat
|
|
WDecoCheat::WDecoCheat(WGuiBase * _it) :
|
|
WGuiDeco(_it)
|
|
{
|
|
bVisible = (options[Options::ACTIVE_PROFILE].str == SECRET_PROFILE);
|
|
}
|
|
void WDecoCheat::Reload()
|
|
{
|
|
bVisible = (options[Options::ACTIVE_PROFILE].str == SECRET_PROFILE);
|
|
}
|
|
bool WDecoCheat::Visible()
|
|
{
|
|
if (bVisible && it && it->Visible()) return true;
|
|
return false;
|
|
}
|
|
bool WDecoCheat::Selectable()
|
|
{
|
|
if (!it || !Visible()) return false;
|
|
return it->Selectable();
|
|
}
|
|
//WDecoConfirm
|
|
|
|
WDecoConfirm::WDecoConfirm(JGuiListener * _listener, WGuiBase * _it) :
|
|
WGuiDeco(_it)
|
|
{
|
|
listener = _listener;
|
|
confirm = "Confirm";
|
|
cancel = "Cancel";
|
|
confirmMenu = NULL;
|
|
bModal = false;
|
|
mState = OP_CONFIRMED;
|
|
}
|
|
|
|
WDecoConfirm::~WDecoConfirm()
|
|
{
|
|
SAFE_DELETE(confirmMenu);
|
|
}
|
|
|
|
void WDecoConfirm::Entering(JButton key)
|
|
{
|
|
setFocus(true);
|
|
|
|
if (it) it->Entering(key);
|
|
|
|
SAFE_DELETE(confirmMenu);
|
|
mState = OP_CONFIRMED;
|
|
confirmMenu = NEW SimpleMenu(JGE::GetInstance(), WResourceManager::Instance(), 444, listener, Fonts::MENU_FONT, 50, 170);
|
|
confirmMenu->Add(1, confirm.c_str());
|
|
confirmMenu->Add(2, cancel.c_str());
|
|
}
|
|
|
|
bool WDecoConfirm::isModal()
|
|
{
|
|
if (bModal || (it && it->isModal())) return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
void WDecoConfirm::setModal(bool val)
|
|
{
|
|
bModal = val;
|
|
}
|
|
void WDecoConfirm::setData()
|
|
{
|
|
if (!it) return;
|
|
|
|
it->setData();
|
|
}
|
|
|
|
bool WDecoConfirm::Leaving(JButton key)
|
|
{
|
|
if (!it) return true;
|
|
|
|
//Choice must be confirmed.
|
|
if (mState == OP_UNCONFIRMED)
|
|
{
|
|
if (!isModal()) setModal(true);
|
|
if (!it->Changed())
|
|
mState = OP_CONFIRMED;
|
|
else
|
|
mState = OP_CONFIRMING;
|
|
}
|
|
|
|
if (mState == OP_CONFIRMED && it->Leaving(key))
|
|
{
|
|
setFocus(false);
|
|
setModal(false);
|
|
SAFE_DELETE(confirmMenu);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
bool WDecoConfirm::CheckUserInput(JButton key)
|
|
{
|
|
if (hasFocus())
|
|
{
|
|
if (mState == OP_CONFIRMED && key == JGE_BTN_OK) mState = OP_UNCONFIRMED;
|
|
|
|
if (mState != OP_CONFIRMING && it)
|
|
{
|
|
if (it->CheckUserInput(key)) return true;
|
|
}
|
|
else if (confirmMenu && confirmMenu->CheckUserInput(key)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void WDecoConfirm::Update(float dt)
|
|
{
|
|
if (hasFocus())
|
|
{
|
|
if (it && mState != OP_CONFIRMING)
|
|
it->Update(dt);
|
|
else
|
|
confirmMenu->Update(dt);
|
|
}
|
|
}
|
|
|
|
void WDecoConfirm::Overlay()
|
|
{
|
|
if (confirmMenu && mState == OP_CONFIRMING) confirmMenu->Render();
|
|
|
|
if (it) it->Overlay();
|
|
}
|
|
|
|
void WDecoConfirm::ButtonPressed(int controllerId, int controlId)
|
|
{
|
|
if (controllerId == 444)
|
|
{
|
|
setModal(false);
|
|
switch (controlId)
|
|
{
|
|
case 1:
|
|
mState = OP_CONFIRMED;
|
|
if (it) it->confirmChange(true);
|
|
break;
|
|
case 2:
|
|
mState = OP_CONFIRMED;
|
|
if (it) it->confirmChange(false);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
it->ButtonPressed(controllerId, controlId);
|
|
}
|
|
|
|
WGuiButton::WGuiButton(WGuiBase* _it, int _controller, int _control, JGuiListener * jgl) :
|
|
WGuiDeco(_it)
|
|
{
|
|
control = _control;
|
|
controller = _controller;
|
|
mListener = jgl;
|
|
}
|
|
|
|
void WGuiButton::updateValue()
|
|
{
|
|
if (mListener) mListener->ButtonPressed(controller, control);
|
|
}
|
|
|
|
bool WGuiButton::CheckUserInput(JButton key)
|
|
{
|
|
if (hasFocus() && key == JGE_BTN_OK)
|
|
{
|
|
updateValue();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
PIXEL_TYPE WGuiButton::getColor(int type)
|
|
{
|
|
if (type == WGuiColor::BACK && hasFocus()) return it->getColor(WGuiColor::BACK_HEADER);
|
|
return it->getColor(type);
|
|
}
|
|
;
|
|
|
|
WGuiSplit::WGuiSplit(WGuiBase* _left, WGuiBase* _right, bool custom) :
|
|
WGuiItem("")
|
|
{
|
|
right = _right;
|
|
left = _left;
|
|
bRight = false;
|
|
if(!custom)
|
|
percentRight = 0.5f;
|
|
else
|
|
percentRight = 0.67f;
|
|
if (!left->Selectable()) bRight = true;
|
|
}
|
|
WGuiSplit::~WGuiSplit()
|
|
{
|
|
SAFE_DELETE(left);
|
|
SAFE_DELETE(right);
|
|
}
|
|
|
|
void WGuiSplit::setData()
|
|
{
|
|
left->setData();
|
|
right->setData();
|
|
}
|
|
void WGuiSplit::setX(float _x)
|
|
{
|
|
x = _x;
|
|
left->setX(x);
|
|
right->setX(x + (1 - percentRight) * width);
|
|
}
|
|
void WGuiSplit::setY(float _y)
|
|
{
|
|
y = _y;
|
|
left->setY(y);
|
|
right->setY(y);
|
|
}
|
|
void WGuiSplit::setWidth(float _w)
|
|
{
|
|
width = _w;
|
|
if (right->Visible())
|
|
left->setWidth((1 - percentRight) * width);
|
|
else
|
|
left->setWidth(width);
|
|
|
|
right->setWidth(percentRight * width);
|
|
}
|
|
void WGuiSplit::setHeight(float _h)
|
|
{
|
|
left->setHeight(_h);
|
|
right->setHeight(_h);
|
|
height = _h;
|
|
}
|
|
float WGuiSplit::getHeight()
|
|
{
|
|
float lH, rH;
|
|
lH = left->getHeight();
|
|
rH = right->getHeight();
|
|
if (lH > rH) return lH;
|
|
|
|
return rH;
|
|
}
|
|
|
|
void WGuiSplit::Render()
|
|
{
|
|
if (right->Visible()) right->Render();
|
|
if (left->Visible()) left->Render();
|
|
}
|
|
|
|
bool WGuiSplit::isModal()
|
|
{
|
|
if (bRight) return right->isModal();
|
|
|
|
return left->isModal();
|
|
}
|
|
void WGuiSplit::setModal(bool val)
|
|
{
|
|
if (bRight) return right->setModal(val);
|
|
|
|
return left->setModal(val);
|
|
}
|
|
|
|
bool WGuiSplit::CheckUserInput(JButton key)
|
|
{
|
|
bool result = false;
|
|
|
|
if (hasFocus())
|
|
{
|
|
int i,j;
|
|
|
|
if (key == JGE_BTN_NONE && JGE::GetInstance()->GetLeftClickCoordinates(i, j))
|
|
{ // a dude clicked somwhere, we're gonna select the closest object from where he clicked
|
|
unsigned int distanceLeft, distanceRight;
|
|
|
|
distanceLeft = static_cast<unsigned int>((left->getY() - j) * (left->getY() - j) + (left->getX() - i) * (left->getX() - i));
|
|
distanceRight = static_cast<unsigned int>((right->getY() - j) * (right->getY() - j) + (right->getX() - i) * (right->getX() - i));
|
|
|
|
if (distanceLeft < distanceRight && bRight)
|
|
{
|
|
key = JGE_BTN_LEFT;
|
|
}
|
|
else if(!bRight && distanceLeft > distanceRight)
|
|
{
|
|
key = JGE_BTN_RIGHT;
|
|
}
|
|
}
|
|
|
|
if (!bRight)
|
|
{
|
|
if (left->CheckUserInput(key)) {
|
|
result = true;
|
|
goto done;
|
|
}
|
|
|
|
if (key == JGE_BTN_RIGHT && !isModal() && right->Selectable() && left->Leaving(JGE_BTN_RIGHT))
|
|
{
|
|
bRight = !bRight;
|
|
right->Entering(JGE_BTN_RIGHT);
|
|
result = true;
|
|
goto done;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (right->CheckUserInput(key)) {
|
|
result = true;
|
|
goto done;
|
|
}
|
|
if (key == JGE_BTN_LEFT && !isModal() && left->Selectable() && right->Leaving(JGE_BTN_LEFT))
|
|
{
|
|
bRight = !bRight;
|
|
left->Entering(JGE_BTN_LEFT);
|
|
result = true;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
}
|
|
done:
|
|
if(result == true)
|
|
{
|
|
JGE::GetInstance()->LeftClickedProcessed();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void WGuiSplit::Update(float dt)
|
|
{
|
|
if (bRight)
|
|
right->Update(dt);
|
|
else
|
|
left->Update(dt);
|
|
}
|
|
|
|
void WGuiSplit::Entering(JButton key)
|
|
{
|
|
mFocus = true;
|
|
if (bRight)
|
|
right->Entering(key);
|
|
else
|
|
left->Entering(key);
|
|
}
|
|
bool WGuiSplit::Leaving(JButton key)
|
|
{
|
|
|
|
if (bRight)
|
|
{
|
|
if (right->Leaving(key))
|
|
{
|
|
mFocus = false;
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (left->Leaving(key))
|
|
{
|
|
mFocus = false;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
void WGuiSplit::Overlay()
|
|
{
|
|
if (bRight)
|
|
right->Overlay();
|
|
else
|
|
left->Overlay();
|
|
}
|
|
void WGuiSplit::Underlay()
|
|
{
|
|
if (bRight)
|
|
right->Underlay();
|
|
else
|
|
left->Underlay();
|
|
}
|
|
void WGuiSplit::ButtonPressed(int controllerId, int controlId)
|
|
{
|
|
if (bRight)
|
|
right->ButtonPressed(controllerId, controlId);
|
|
else
|
|
left->ButtonPressed(controllerId, controlId);
|
|
}
|
|
void WGuiSplit::Reload()
|
|
{
|
|
left->Reload();
|
|
right->Reload();
|
|
}
|
|
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, JButton prev, bool dPad, WSyncable * syncme) : WGuiItem("")
|
|
{
|
|
buttonNext = next;
|
|
buttonPrev = prev;
|
|
currentItem = -1;
|
|
mDPad = dPad;
|
|
sync = syncme;
|
|
held = JGE_BTN_NONE;
|
|
}
|
|
WGuiMenu::~WGuiMenu()
|
|
{
|
|
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); it++)
|
|
SAFE_DELETE(*it);
|
|
}
|
|
void WGuiMenu::setData()
|
|
{
|
|
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); it++)
|
|
(*it)->setData();
|
|
}
|
|
;
|
|
|
|
void WGuiMenu::Reload()
|
|
{
|
|
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); it++)
|
|
(*it)->Reload();
|
|
}
|
|
;
|
|
|
|
void WGuiMenu::Render()
|
|
{
|
|
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); it++)
|
|
(*it)->Render();
|
|
}
|
|
void WGuiMenu::confirmChange(bool confirmed)
|
|
{
|
|
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); it++)
|
|
(*it)->confirmChange(confirmed);
|
|
}
|
|
|
|
void WGuiMenu::ButtonPressed(int controllerId, int controlId)
|
|
{
|
|
WGuiBase * it = Current();
|
|
if (!it) return;
|
|
it->ButtonPressed(controllerId, controlId);
|
|
}
|
|
|
|
WGuiBase * WGuiMenu::Current()
|
|
{
|
|
if (currentItem >= 0 && currentItem < (int) items.size()) return items[currentItem];
|
|
return NULL;
|
|
}
|
|
void WGuiMenu::Add(WGuiBase * it)
|
|
{
|
|
if (it) items.push_back(it);
|
|
}
|
|
bool WGuiMenu::CheckUserInput(JButton key)
|
|
{
|
|
bool result = false;
|
|
bool kidModal = false;
|
|
int nbitems = (int) items.size();
|
|
JGE * mEngine = JGE::GetInstance();
|
|
int i, j;
|
|
|
|
if (!mEngine->GetButtonState(held)) //Key isn't held down.
|
|
held = JGE_BTN_NONE;
|
|
|
|
if (mEngine->GetLeftClickCoordinates(i, j))
|
|
{ // a dude clicked somwhere, we're gonna select the closest object from where he clicked
|
|
int n = currentItem;
|
|
unsigned int distance2;
|
|
unsigned int minDistance2 = -1;
|
|
for(size_t k = 0; k < items.size(); k++)
|
|
{
|
|
WGuiBase* pItem = items[k];
|
|
distance2 = static_cast<unsigned int>((pItem->getY() - j) * (pItem->getY() - j) + (pItem->getX() - i) * (pItem->getX() - i));
|
|
if (distance2 < minDistance2 && pItem->Selectable())
|
|
{
|
|
minDistance2 = distance2;
|
|
n = k;
|
|
}
|
|
}
|
|
|
|
if (n != currentItem && items[n]->Selectable())
|
|
{
|
|
setSelected(n);
|
|
mEngine->LeftClickedProcessed();
|
|
if (sync) syncMove();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (currentItem >= 0 && currentItem < nbitems) kidModal = items[currentItem]->isModal();
|
|
|
|
if (!kidModal && hasFocus())
|
|
{
|
|
if (isButtonDir(key, -1))
|
|
{
|
|
held = buttonPrev;
|
|
duration = 0;
|
|
if (prevItem()) return true;
|
|
}
|
|
else if (held == buttonPrev && duration > 1)
|
|
{
|
|
duration = .92f;
|
|
if (prevItem()) return true;
|
|
}
|
|
else if (isButtonDir(key, 1))
|
|
{
|
|
held = buttonNext;
|
|
duration = 0;
|
|
if (nextItem()) return true;
|
|
}
|
|
else if (held == buttonNext && duration > 1)
|
|
{
|
|
duration = .92f;
|
|
if (nextItem()) return true;
|
|
}
|
|
}
|
|
|
|
if (currentItem >= 0 && currentItem < nbitems) result = items[currentItem]->CheckUserInput(key);
|
|
|
|
mEngine->LeftClickedProcessed();
|
|
|
|
return result;
|
|
}
|
|
void WGuiMenu::syncMove()
|
|
{
|
|
if (!sync) return;
|
|
int i = currentItem - sync->getPos();
|
|
|
|
while (i < 0 && sync->prev())
|
|
i = currentItem - sync->getPos();
|
|
while (i > 0 && sync->next())
|
|
i = currentItem - sync->getPos();
|
|
}
|
|
bool WGuiMenu::isButtonDir(JButton key, int dir)
|
|
{
|
|
if (!mDPad) return ((dir > 0 && key == buttonNext) || (dir <= 0 && key == buttonPrev));
|
|
|
|
if (dir <= 0)
|
|
{
|
|
switch (buttonPrev)
|
|
{
|
|
case JGE_BTN_LEFT:
|
|
if (key == JGE_BTN_UP) return true;
|
|
break;
|
|
case JGE_BTN_UP:
|
|
if (key == JGE_BTN_LEFT) return true;
|
|
break;
|
|
default:
|
|
; // Nothing
|
|
}
|
|
return (key == buttonPrev);
|
|
}
|
|
else
|
|
{
|
|
switch (buttonNext)
|
|
{
|
|
case JGE_BTN_RIGHT:
|
|
if (key == JGE_BTN_DOWN) return true;
|
|
break;
|
|
case JGE_BTN_DOWN:
|
|
if (key == JGE_BTN_RIGHT) return true;
|
|
break;
|
|
default:
|
|
; // Nothing
|
|
}
|
|
return (key == buttonNext);
|
|
}
|
|
}
|
|
void WGuiMenu::Update(float dt)
|
|
{
|
|
int nbitems = (int) items.size();
|
|
|
|
if (held) duration += dt;
|
|
|
|
if (currentItem >= 0 && currentItem < nbitems) items[currentItem]->Update(dt);
|
|
|
|
for (int i = 0; i < nbitems; i++)
|
|
{
|
|
if (i != currentItem) items[i]->Update(dt);
|
|
}
|
|
}
|
|
|
|
bool WGuiMenu::nextItem()
|
|
{
|
|
int potential = currentItem;
|
|
int nbitems = (int) items.size();
|
|
if (nbitems < 2) return false;
|
|
|
|
WGuiBase * now = NULL;
|
|
if (currentItem < nbitems && currentItem > -1) now = items[currentItem];
|
|
|
|
if (potential < nbitems - 1)
|
|
potential++;
|
|
else
|
|
potential = 0;
|
|
|
|
while (potential < nbitems - 1 && items[potential]->Selectable() == false)
|
|
potential++;
|
|
if (potential != currentItem && (!now || now->Leaving(buttonNext)))
|
|
{
|
|
currentItem = potential;
|
|
items[currentItem]->Entering(buttonNext);
|
|
|
|
if (sync) syncMove();
|
|
return true;
|
|
}
|
|
|
|
if (sync) syncMove();
|
|
return false;
|
|
}
|
|
|
|
bool WGuiMenu::prevItem()
|
|
{
|
|
int potential = currentItem;
|
|
WGuiBase * now = NULL;
|
|
int nbitems = (int) items.size();
|
|
if (nbitems < 2) return false;
|
|
|
|
if (currentItem < (int) items.size() && currentItem > -1) now = items[currentItem];
|
|
|
|
if (potential > 0)
|
|
potential--;
|
|
else
|
|
potential = nbitems - 1;
|
|
|
|
while (potential > 0 && items[potential]->Selectable() == false)
|
|
potential--;
|
|
|
|
if ( (!(potential < 0 || !items[potential]->Selectable()))
|
|
&& (potential != currentItem && (!now || now->Leaving(buttonNext))))
|
|
{
|
|
currentItem = potential;
|
|
items[currentItem]->Entering(buttonPrev);
|
|
if (sync) syncMove();
|
|
return true;
|
|
}
|
|
if (sync) syncMove();
|
|
return false;
|
|
}
|
|
|
|
void WGuiMenu::setModal(bool val)
|
|
{
|
|
WGuiBase* c = Current();
|
|
if (c) c->setModal(val);
|
|
}
|
|
bool WGuiMenu::isModal()
|
|
{
|
|
WGuiBase* c = Current();
|
|
if (c) return c->isModal();
|
|
|
|
return false;
|
|
}
|
|
//WGuiTabMenu
|
|
void WGuiTabMenu::Add(WGuiBase * it)
|
|
{
|
|
if (it)
|
|
{
|
|
it->setY(it->getY() + 35);
|
|
it->setHeight(it->getHeight() - 35);
|
|
WGuiMenu::Add(it);
|
|
}
|
|
}
|
|
|
|
void WGuiTabMenu::Render()
|
|
{
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
|
|
if (!items.size()) return;
|
|
|
|
float offset = x;
|
|
mFont->SetScale(0.8f);
|
|
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); it++)
|
|
{
|
|
float w = mFont->GetStringWidth(_((*it)->getDisplay()).c_str());
|
|
mFont->SetColor((*it)->getColor(WGuiColor::TEXT_TAB));
|
|
renderer->FillRoundRect(offset + 6.5f, 5, w + 6.5f, 25, 0, (*it)->getColor(WGuiColor::BACK_TAB));
|
|
//inside border
|
|
renderer->DrawRoundRect(offset + 6.5f, 5, w + 6.5f, 25, 0, ARGB(180,89,89,89));
|
|
//outside border
|
|
//renderer->DrawRoundRect(offset + 5.5f, 4, w + 8.5f, 27, 0, ARGB(180,240,240,240));
|
|
mFont->DrawString(_((*it)->getDisplay()).c_str(), offset + 10, 10);
|
|
offset += w + 10 + 2;
|
|
}
|
|
mFont->SetScale(1);
|
|
|
|
WGuiBase * c = Current();
|
|
if (c) c->Render();
|
|
}
|
|
|
|
bool WGuiTabMenu::CheckUserInput(JButton key)
|
|
{
|
|
bool result = false;
|
|
bool kidModal = false;
|
|
int nbitems = (int) items.size();
|
|
JGE * mEngine = JGE::GetInstance();
|
|
int i, j;
|
|
|
|
if (!mEngine->GetButtonState(held)) //Key isn't held down.
|
|
held = JGE_BTN_NONE;
|
|
|
|
if (mEngine->GetLeftClickCoordinates(i, j))
|
|
{
|
|
if(j <= 25)
|
|
{ // a dude clicked in the tab title bar, let's compute which tab from i
|
|
float offset = x;
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
mFont->SetScale(0.8f);
|
|
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); it++)
|
|
{
|
|
float w = mFont->GetStringWidth(_((*it)->getDisplay()).c_str());
|
|
|
|
if(i >= offset+5 && i <= offset+w+10+2)
|
|
{
|
|
setSelected(it);
|
|
mEngine->LeftClickedProcessed();
|
|
return true;
|
|
}
|
|
offset += w + 10 + 2;
|
|
}
|
|
mFont->SetScale(1);
|
|
}
|
|
}
|
|
|
|
if (currentItem >= 0 && currentItem < nbitems) kidModal = items[currentItem]->isModal();
|
|
|
|
if (!kidModal && hasFocus())
|
|
{
|
|
if (isButtonDir(key, -1))
|
|
{
|
|
held = buttonPrev;
|
|
duration = 0;
|
|
if (prevItem()) return true;
|
|
}
|
|
else if (held == buttonPrev && duration > 1)
|
|
{
|
|
duration = .92f;
|
|
if (prevItem()) return true;
|
|
}
|
|
else if (isButtonDir(key, 1))
|
|
{
|
|
held = buttonNext;
|
|
duration = 0;
|
|
if (nextItem()) return true;
|
|
}
|
|
else if (held == buttonNext && duration > 1)
|
|
{
|
|
duration = .92f;
|
|
if (nextItem()) return true;
|
|
}
|
|
}
|
|
|
|
if (currentItem >= 0 && currentItem < nbitems) result = items[currentItem]->CheckUserInput(key);
|
|
|
|
return result;
|
|
}
|
|
|
|
void WGuiTabMenu::save()
|
|
{
|
|
confirmChange(true);
|
|
setData();
|
|
::options.save();
|
|
}
|
|
|
|
//WGuiAward
|
|
void WGuiAward::Overlay()
|
|
{
|
|
JRenderer * r = JRenderer::GetInstance();
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
mFont->SetScale(0.8f);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT));
|
|
|
|
string s = details;
|
|
if (s.size())
|
|
{
|
|
float fW = mFont->GetStringWidth(s.c_str());
|
|
float fH = mFont->GetHeight();
|
|
|
|
if (fH < 16) fH = 18;
|
|
JQuadPtr button = WResourceManager::Instance()->RetrieveQuad("iconspsp.png", (float) 4 * 32, 0, 32, 32, "", RETRIEVE_NORMAL);
|
|
|
|
r->FillRoundRect(5, 10, fW + 32, fH + 2, 2, getColor(WGuiColor::BACK));
|
|
if (button) r->RenderQuad(button.get(), 10, 12, 0, .5, .5);
|
|
mFont->DrawString(::_(s), 30, 16);
|
|
}
|
|
|
|
mFont->SetScale(1);
|
|
}
|
|
void WGuiAward::Underlay()
|
|
{
|
|
char buf[1024];
|
|
JQuadPtr trophy;
|
|
|
|
#if defined (PSP)
|
|
string n = id ? Options::getName(id) : textId;
|
|
if (n.size())
|
|
{
|
|
sprintf(buf, "psptrophy_%s.png", n.c_str()); //Trophy specific to the award
|
|
trophy = WResourceManager::Instance()->RetrieveTempQuad(buf); //Themed version...
|
|
}
|
|
|
|
if (!trophy && id >= Options::SET_UNLOCKS)
|
|
{
|
|
trophy = WResourceManager::Instance()->RetrieveTempQuad("psptrophy_set.png"); //TODO FIXME: Should look in set dir too.
|
|
}
|
|
|
|
if (!trophy.get()) //Fallback to basic trophy image.
|
|
trophy = WResourceManager::Instance()->RetrieveTempQuad("psptrophy.png");
|
|
#else
|
|
string n = id ? Options::getName(id) : textId;
|
|
if (n.size())
|
|
{
|
|
sprintf(buf, "trophy_%s.png", n.c_str()); //Trophy specific to the award
|
|
trophy = WResourceManager::Instance()->RetrieveTempQuad(buf); //Themed version...
|
|
}
|
|
|
|
if (!trophy && id >= Options::SET_UNLOCKS)
|
|
{
|
|
trophy = WResourceManager::Instance()->RetrieveTempQuad("trophy_set.png"); //TODO FIXME: Should look in set dir too.
|
|
}
|
|
|
|
if (!trophy.get()) //Fallback to basic trophy image.
|
|
trophy = WResourceManager::Instance()->RetrieveTempQuad("trophy.png");
|
|
#endif
|
|
|
|
if (trophy.get())
|
|
{
|
|
trophy->SetHotSpot(0,trophy->mHeight);
|
|
if(trophy->mHeight == 268.f && trophy->mWidth == 203.f)
|
|
{
|
|
trophy->SetHotSpot(0,0);
|
|
JRenderer::GetInstance()->RenderQuad(trophy.get(), 0, SCREEN_HEIGHT-trophy->mHeight);
|
|
}
|
|
else if(trophy->mHeight == 1268.f && trophy->mWidth == 1203.f)
|
|
{
|
|
JRenderer::GetInstance()->RenderQuad(trophy.get(), -17, SCREEN_HEIGHT-35, 0, 240.f / trophy->mWidth, 210.f / trophy->mHeight);
|
|
}
|
|
else
|
|
JRenderer::GetInstance()->RenderQuad(trophy.get(), 0, SCREEN_HEIGHT, 0, 171.f / trophy->mWidth, 192.f / trophy->mHeight);
|
|
}
|
|
|
|
}
|
|
void WGuiAward::Render()
|
|
{
|
|
GameOptionAward * goa = id ? dynamic_cast<GameOptionAward*> (&options[id]) : dynamic_cast<GameOptionAward*> (&options[textId]);
|
|
|
|
if (!goa) return;
|
|
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
mFont->SetScale(1);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT));
|
|
|
|
float myX = x;
|
|
float myY = y;
|
|
float fH = mFont->GetHeight();
|
|
float fM = fH / 5; //Font Margin is 20% font height
|
|
|
|
myX += fM;
|
|
JRenderer::GetInstance()->FillRoundRect(x - fM / 2, y - fM, getWidth() - fM, fH - fM, fM, getColor(WGuiColor::BACK_TAB));
|
|
mFont->DrawString(::_(displayValue).c_str(), myX, myY, JGETEXT_LEFT);
|
|
|
|
myY += fH + 3 * fM;
|
|
mFont->SetScale(.75);
|
|
fH = mFont->GetHeight();
|
|
if (text.size())
|
|
{
|
|
mFont->DrawString(_(text.c_str()), myX, myY, JGETEXT_LEFT);
|
|
myY += fH + fM;
|
|
}
|
|
string s = goa->menuStr();
|
|
if (s.size())
|
|
{
|
|
mFont->DrawString(s.c_str(), myX, myY, JGETEXT_LEFT);
|
|
myY += fH + fM;
|
|
}
|
|
setHeight(myY - y);
|
|
mFont->SetScale(1);
|
|
}
|
|
|
|
WGuiAward::WGuiAward(int _id, string name, string _text, string _details) :
|
|
WGuiItem(name)
|
|
{
|
|
id = _id;
|
|
text = _text;
|
|
height = 60;
|
|
details = _details;
|
|
}
|
|
|
|
WGuiAward::WGuiAward(string _id, string name, string _text, string _details) :
|
|
WGuiItem(name)
|
|
{
|
|
id = 0;
|
|
textId = _id;
|
|
text = _text;
|
|
height = 60;
|
|
details = _details;
|
|
}
|
|
|
|
WGuiAward::~WGuiAward()
|
|
{
|
|
GameOptionAward * goa = dynamic_cast<GameOptionAward*> (&options[id]);
|
|
if (goa) goa->setViewed(true);
|
|
}
|
|
bool WGuiAward::Visible()
|
|
{
|
|
//WGuiAward is only visible when it's tied to an already achieved award.
|
|
GameOptionAward * goa = id ? dynamic_cast<GameOptionAward*> (&options[id]) : dynamic_cast<GameOptionAward*> (&options[textId]);
|
|
if (!goa || !goa->number) return false;
|
|
return true;
|
|
}
|
|
|
|
//WGuiImage
|
|
WGuiImage::WGuiImage(WDataSource * wds, float _w, float _h, int _margin) :
|
|
WGuiItem("")
|
|
{
|
|
imgW = _w;
|
|
imgH = _h;
|
|
margin = _margin;
|
|
source = wds;
|
|
}
|
|
|
|
void WGuiImage::imageScale(float _w, float _h)
|
|
{
|
|
imgH = _h;
|
|
imgW = _w;
|
|
}
|
|
|
|
float WGuiImage::getHeight()
|
|
{
|
|
JQuadPtr q = source->getImage();
|
|
|
|
if (imgH == 0)
|
|
{
|
|
if (source && q.get())
|
|
return MAX(height,q->mHeight+(2*margin));
|
|
}
|
|
|
|
return MAX(height,imgH+(2*margin));
|
|
}
|
|
|
|
void WGuiImage::Render()
|
|
{
|
|
if (!source) return;
|
|
|
|
JQuadPtr q = source->getImage();
|
|
if (q)
|
|
{
|
|
float xS = 1, yS = 1;
|
|
if (imgH != 0 && q->mHeight != 0) yS = imgH / q->mHeight;
|
|
if (imgW != 0 && q->mWidth != 0) xS = imgW / q->mWidth;
|
|
|
|
JRenderer::GetInstance()->RenderQuad(q.get(), x + margin, y + margin, 0, xS, yS);
|
|
}
|
|
}
|
|
|
|
WGuiCardImage::WGuiCardImage(WDataSource * wds, bool _thumb) :
|
|
WGuiImage(wds)
|
|
{
|
|
bThumb = _thumb;
|
|
}
|
|
;
|
|
|
|
void WGuiCardImage::Render()
|
|
{
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
MTGCard * c = NULL;
|
|
Pos p(x + margin, y + margin, 1, 0, 255);
|
|
|
|
if (!source || (c = source->getCard(mOffset.getPos())) == NULL)
|
|
{ //No card, use card back.
|
|
JQuadPtr q;
|
|
if (bThumb)
|
|
{
|
|
q = WResourceManager::Instance()->GetQuad(kGenericCardThumbnailID);
|
|
#if defined WIN32 || defined LINUX
|
|
if(!q)
|
|
q = WResourceManager::Instance()->GetQuad(kGenericCardID);
|
|
#endif
|
|
}
|
|
else
|
|
q = WResourceManager::Instance()->GetQuad(kGenericCardID);
|
|
float scale = p.actZ * 257.f / q->mHeight;
|
|
q->SetColor(ARGB(255,255,255,255));
|
|
renderer->RenderQuad(q.get(), p.x, p.y, 0, scale, scale);
|
|
}
|
|
else
|
|
{ //Have card.
|
|
if (bThumb)
|
|
{ //Thumbnail.
|
|
JQuadPtr q;
|
|
if (!options[Options::DISABLECARDS].number)
|
|
{
|
|
q = source->getThumb(mOffset.getPos());
|
|
#if defined WIN32 || defined LINUX
|
|
if(!q)
|
|
q = source->getImage(mOffset.getPos());
|
|
#endif
|
|
}
|
|
if (!q.get())
|
|
{
|
|
q = CardGui::AlternateThumbQuad(c);
|
|
if (q.get() == NULL)
|
|
return; //TODO Some kind of error image.
|
|
}
|
|
renderer->RenderQuad(q.get(), p.x, p.y);
|
|
}
|
|
else
|
|
{ //Normal card.
|
|
JQuadPtr q = source->getImage(mOffset.getPos());
|
|
|
|
int mode = (!q.get() || options[Options::DISABLECARDS].number) ? DrawMode::kText : DrawMode::kNormal;
|
|
CardGui::DrawCard(c, p, mode);
|
|
}
|
|
}
|
|
}
|
|
|
|
//WGuiCardDistort
|
|
WGuiCardDistort::WGuiCardDistort(WDataSource * wds, bool _thumb, WDataSource *) :
|
|
WGuiCardImage(wds, _thumb)
|
|
{
|
|
mesh = NEW hgeDistortionMesh(2, 2);
|
|
distortSrc = NULL;
|
|
}
|
|
WGuiCardDistort::~WGuiCardDistort()
|
|
{
|
|
SAFE_DELETE(mesh);
|
|
}
|
|
|
|
void WGuiCardDistort::Render()
|
|
{
|
|
JQuadPtr q;
|
|
|
|
if (distortSrc)
|
|
{
|
|
WDistort * dt = distortSrc->getDistort(mOffset.getPos());
|
|
if (dt) xy = *dt;
|
|
}
|
|
|
|
if (!source)
|
|
{
|
|
//Default to back.
|
|
if (bThumb)
|
|
{
|
|
q = WResourceManager::Instance()->GetQuad(kGenericCardThumbnailID);
|
|
#if defined WIN32 || defined LINUX
|
|
if(!q)
|
|
q = WResourceManager::Instance()->GetQuad(kGenericCardID);
|
|
#endif
|
|
}
|
|
else
|
|
q = WResourceManager::Instance()->GetQuad(kGenericCardID);
|
|
}
|
|
else
|
|
{
|
|
MTGCard * c = source->getCard(mOffset.getPos());
|
|
if (!c) return;
|
|
|
|
if (bThumb)
|
|
{
|
|
q = source->getThumb(mOffset.getPos());
|
|
#if defined WIN32 || defined LINUX
|
|
if(!q)
|
|
q = source->getImage(mOffset.getPos());
|
|
#endif
|
|
if (!q || options[Options::DISABLECARDS].number) q = CardGui::AlternateThumbQuad(c);
|
|
}
|
|
else
|
|
{
|
|
q = source->getImage(mOffset.getPos());
|
|
if (!q || options[Options::DISABLECARDS].number) q = CardGui::AlternateThumbQuad(c); //TODO alternateX should render to texture.
|
|
}
|
|
}
|
|
if (!q.get()) return;
|
|
mesh->SetTexture(q->mTex);
|
|
float x0, y0, w0, h0;
|
|
q->GetTextureRect(&x0, &y0, &w0, &h0);
|
|
mesh->SetTextureRect(x0, y0, w0, h0);
|
|
mesh->Clear(ARGB(0xFF,0xFF,0xFF,0xFF));
|
|
mesh->SetDisplacement(0, 0, xy[0], xy[1], HGEDISP_NODE);
|
|
mesh->SetDisplacement(1, 0, xy[2] - w0, xy[3], HGEDISP_NODE);
|
|
mesh->SetDisplacement(0, 1, xy[4], xy[5] - h0, HGEDISP_NODE);
|
|
mesh->SetDisplacement(1, 1, xy[6] - w0, xy[7] - h0, HGEDISP_NODE);
|
|
if (hasFocus())
|
|
{
|
|
mesh->SetColor(1, 1, ARGB(255,200,200,200));
|
|
mesh->SetColor(0, 1, ARGB(255,200,200,200));
|
|
mesh->SetColor(1, 0, ARGB(255,200,200,200));
|
|
mesh->SetColor(0, 0, ARGB(255,255,255,200));
|
|
}
|
|
else
|
|
{
|
|
mesh->SetColor(1, 1, ARGB(255,100,100,100));
|
|
mesh->SetColor(0, 1, ARGB(255,100,100,100));
|
|
mesh->SetColor(1, 0, ARGB(255,100,100,100));
|
|
mesh->SetColor(0, 0, ARGB(255,200,200,200));
|
|
}
|
|
mesh->Render(0, 0);
|
|
|
|
}
|
|
|
|
//WDistort
|
|
WDistort::WDistort()
|
|
{
|
|
for (int i = 0; i < 8; i++)
|
|
xy[i] = 0;
|
|
}
|
|
|
|
float & WDistort::operator[](int p)
|
|
{
|
|
return xy[p];
|
|
}
|
|
|
|
WDistort::WDistort(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
|
|
{
|
|
xy[0] = x1;
|
|
xy[1] = y1;
|
|
xy[2] = x2;
|
|
xy[3] = y2;
|
|
xy[4] = x3;
|
|
xy[5] = y3;
|
|
xy[6] = x4;
|
|
xy[7] = y4;
|
|
}
|
|
|
|
//WGuiListRow
|
|
|
|
void WGuiListRow::Render()
|
|
{
|
|
int start = 0, nowPos = 0;
|
|
int nbitems = (int) items.size();
|
|
|
|
//List is empty.
|
|
if (!items.size() && failMsg != "")
|
|
{
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::OPTION_FONT);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT_FAIL));
|
|
mFont->DrawString(_(failMsg).c_str(), x + width / 2, y, JGETEXT_RIGHT);
|
|
return;
|
|
}
|
|
|
|
//Force a selectable option.
|
|
if (currentItem == -1)
|
|
{
|
|
for (int i = 0; i < nbitems; i++)
|
|
{
|
|
if (items[i]->Selectable())
|
|
{
|
|
currentItem = i;
|
|
if (hasFocus()) items[currentItem]->Entering(JGE_BTN_NONE);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
nowPos = 4;
|
|
float nowVPos = 4;
|
|
float tallestRow = 0;
|
|
int numRows = 1;
|
|
float cTallest = 0;
|
|
|
|
//Render items.
|
|
if (start >= 0)
|
|
{
|
|
//Render current underlay.
|
|
if (currentItem >= 0 && currentItem < nbitems && items[currentItem]->Visible()) items[currentItem]->Underlay();
|
|
|
|
for (int pos = 0; pos < nbitems; pos++)
|
|
{
|
|
if (!items[pos]->Visible()) continue;
|
|
|
|
items[pos]->setX(x + nowPos);
|
|
items[pos]->setY(y + nowVPos);
|
|
items[pos]->setWidth(items[pos]->minWidth());
|
|
float temp = items[pos]->getHeight() + 3;
|
|
if (temp > tallestRow) tallestRow = temp;
|
|
if (temp > cTallest) cTallest = temp;
|
|
nowPos += static_cast<int> (items[pos]->getWidth() + 5);
|
|
renderBack(items[pos]);
|
|
if (x + nowPos + items[pos]->getWidth() + 10 > SCREEN_WIDTH)
|
|
{
|
|
nowPos = 0 + 20; //Indent newlines.
|
|
nowVPos += cTallest;
|
|
cTallest = 0;
|
|
numRows++;
|
|
}
|
|
items[pos]->Render();
|
|
if (nowVPos > SCREEN_HEIGHT) break;
|
|
}
|
|
|
|
//Render current overlay.
|
|
if (currentItem >= 0 && currentItem < nbitems && items[currentItem]->Visible()) items[currentItem]->Overlay();
|
|
}
|
|
setHeight(tallestRow * numRows + 10);
|
|
}
|
|
|
|
WGuiListRow::WGuiListRow(string n, WSyncable * s) :
|
|
WGuiList(n, s)
|
|
{
|
|
buttonNext = JGE_BTN_RIGHT;
|
|
buttonPrev = JGE_BTN_LEFT;
|
|
width = SCREEN_WIDTH;
|
|
height = 20;
|
|
}
|
|
|
|
//WGuiFilterUI
|
|
bool WGuiFilters::Finish(bool emptyset)
|
|
{
|
|
bFinished = true;
|
|
string src;
|
|
if (source)
|
|
{
|
|
src = getCode();
|
|
source->clearFilters();
|
|
if (src.size())
|
|
{
|
|
WCFilterFactory * wc = WCFilterFactory::GetInstance();
|
|
WCardFilter * f = wc->Construct(src);
|
|
if (recolorTo > -1 && recolorTo < Constants::NB_Colors)
|
|
{
|
|
f = NEW WCFilterAND(f, NEW WCFilterColor(recolorTo));
|
|
}
|
|
source->addFilter(f);
|
|
}
|
|
else
|
|
{
|
|
if (recolorTo > -1 && recolorTo < Constants::NB_Colors)
|
|
{
|
|
WCardFilter * f = NEW WCFilterColor(recolorTo);
|
|
source->addFilter(f);
|
|
}
|
|
}
|
|
if ((!source->Size() && !emptyset))
|
|
{
|
|
source->clearFilters(); //TODO: Pop a "No results found" warning
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void WGuiFilters::ButtonPressed(int controllerId, int controlId)
|
|
{
|
|
if (controllerId == -102)
|
|
{
|
|
if (controlId == -10)
|
|
{
|
|
WGuiListRow * wgl = NEW WGuiListRow("");
|
|
wgl->Add(NEW WGuiFilterItem(this));
|
|
list->Add(wgl);
|
|
}
|
|
else if (controlId == -11)
|
|
{
|
|
Finish();
|
|
}
|
|
else
|
|
{
|
|
if (source) source->clearFilters();
|
|
SAFE_DELETE(list);
|
|
buildList();
|
|
}
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
if (list != NULL) list->ButtonPressed(controllerId, controlId);
|
|
}
|
|
}
|
|
|
|
void WGuiFilters::buildList()
|
|
{
|
|
list = NEW WGuiList("");
|
|
WGuiButton * l = NEW WGuiButton(NEW WGuiItem("Add Filter"), -102, -10, this);
|
|
WGuiButton * r = NEW WGuiButton(NEW WGuiItem("Return"), -102, -11, this);
|
|
WGuiButton * mid = NEW WGuiButton(NEW WGuiItem("Clear"), -102, -66, this);
|
|
WGuiSplit * sub = NEW WGuiSplit(mid, r);
|
|
sub->setHeight(25);
|
|
sub->setWidth(240);
|
|
l->setHeight(25);
|
|
l->setWidth(160);
|
|
WGuiSplit * wgs = NEW WGuiSplit(l, sub, true);
|
|
//WGuiSplit * wgs = NEW WGuiSplit(mid, r);
|
|
subMenu = NULL;
|
|
list->Add(NEW WGuiHeader(displayValue));
|
|
//list->Add(l);
|
|
list->Add(wgs);
|
|
list->Entering(JGE_BTN_NONE);
|
|
}
|
|
|
|
WGuiFilters::WGuiFilters(string header, WSrcCards * src) : WGuiItem(header)
|
|
{
|
|
bFinished = false;
|
|
source = src;
|
|
recolorTo = -1;
|
|
buildList();
|
|
}
|
|
|
|
void WGuiFilters::recolorFilter(int color)
|
|
{
|
|
recolorTo = color;
|
|
}
|
|
|
|
string WGuiFilters::getCode()
|
|
{
|
|
if (!list) return "";
|
|
string res;
|
|
vector<WGuiBase*>::iterator row, col;
|
|
for (row = list->items.begin(); row != list->items.end(); row++)
|
|
{
|
|
WGuiList * wgl = dynamic_cast<WGuiList*> (*row);
|
|
if (wgl)
|
|
{
|
|
if (res.size())
|
|
res += "|(";
|
|
else
|
|
res += "(";
|
|
for (col = wgl->items.begin(); col != wgl->items.end(); col++)
|
|
{
|
|
WGuiFilterItem * fi = dynamic_cast<WGuiFilterItem*> (*col);
|
|
if (fi)
|
|
{
|
|
string gc = fi->getCode();
|
|
if (res.size() && gc.size() && res[res.size() - 1] != '(') res += "&";
|
|
res += gc;
|
|
}
|
|
}
|
|
res += ")";
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
void WGuiFilters::setSrc(WSrcCards * wsc)
|
|
{
|
|
source = wsc;
|
|
}
|
|
|
|
void WGuiFilters::Update(float dt)
|
|
{
|
|
if (subMenu && !subMenu->isClosed()) subMenu->Update(dt);
|
|
if (list)
|
|
{
|
|
list->Update(dt);
|
|
WGuiList * wgl = dynamic_cast<WGuiList*> (list->Current());
|
|
if (!wgl) return;
|
|
vector<WGuiBase*>::iterator it;
|
|
bool bDeleted = false;
|
|
for (it = wgl->items.begin(); it != wgl->items.end(); it++)
|
|
{
|
|
WGuiFilterItem * wgfi = dynamic_cast<WGuiFilterItem*> (*it);
|
|
if (!wgfi || wgfi->mState != WGuiFilterItem::STATE_REMOVE) continue;
|
|
SAFE_DELETE(*it);
|
|
it = wgl->items.erase(it);
|
|
bDeleted = true;
|
|
}
|
|
if (bDeleted) wgl->Entering(JGE_BTN_NONE);
|
|
}
|
|
}
|
|
|
|
void WGuiFilters::Entering(JButton key)
|
|
{
|
|
bFinished = false;
|
|
WGuiItem::Entering(key);
|
|
}
|
|
|
|
void WGuiFilters::Render()
|
|
{
|
|
if (!list) return; //Hurrah for paranoia.
|
|
JRenderer * r = JRenderer::GetInstance();
|
|
float tX, tY;
|
|
tX = getX();
|
|
tY = getY();
|
|
r->FillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, ARGB(128,0,0,0));
|
|
list->setX(tX);
|
|
list->setY(tY);
|
|
list->Render();
|
|
|
|
if (subMenu && !subMenu->isClosed()) subMenu->Render();
|
|
}
|
|
|
|
bool WGuiFilters::CheckUserInput(JButton key)
|
|
{
|
|
if (subMenu && !subMenu->isClosed() && subMenu->CheckUserInput(key)) return true;
|
|
|
|
if (key == JGE_BTN_SEC)
|
|
{//|| key == JGE_BTN_MENU){
|
|
//TODO Pop up a "Are you sure?" dialog.
|
|
return true;
|
|
}
|
|
if (list)
|
|
{
|
|
return list->CheckUserInput(key);
|
|
}
|
|
return WGuiItem::CheckUserInput(key);
|
|
}
|
|
|
|
WGuiFilters::~WGuiFilters()
|
|
{
|
|
SAFE_DELETE(list);
|
|
SAFE_DELETE(subMenu);
|
|
}
|
|
|
|
void WGuiFilters::addColumn()
|
|
{
|
|
if (!list) return;
|
|
WGuiList * wgl = dynamic_cast<WGuiList*> (list->Current());
|
|
if (wgl)
|
|
{
|
|
wgl->currentItem = wgl->items.size() - 1;
|
|
wgl->Add(NEW WGuiFilterItem(this));
|
|
}
|
|
}
|
|
|
|
bool WGuiFilters::isAvailableCode(string code)
|
|
{
|
|
if (!list) return false;
|
|
WGuiList * wgl = dynamic_cast<WGuiList*> (list->Current());
|
|
if (wgl)
|
|
{
|
|
vector<WGuiBase*>::iterator it;
|
|
for (it = wgl->items.begin(); it != wgl->items.end(); it++)
|
|
{
|
|
WGuiFilterItem * wgfi = dynamic_cast<WGuiFilterItem*> (*it);
|
|
if (!wgfi || wgfi->mState != WGuiFilterItem::STATE_FINISHED) continue;
|
|
if (!wgfi->mCode.size()) continue;
|
|
if (wgfi->mCode == code) return false;
|
|
}
|
|
return true;
|
|
}
|
|
return false; //For some reason, we don't have any rows?
|
|
}
|
|
|
|
bool WGuiFilters::isAvailable(int type)
|
|
{
|
|
if (!list) return false;
|
|
int colors = 0, ma = 0;
|
|
WGuiList * wgl = dynamic_cast<WGuiList*> (list->Current());
|
|
if (wgl)
|
|
{
|
|
vector<WGuiBase*>::iterator it;
|
|
for (it = wgl->items.begin(); it != wgl->items.end(); it++)
|
|
{
|
|
WGuiFilterItem * wgfi = dynamic_cast<WGuiFilterItem*> (*it);
|
|
if (!wgfi || wgfi->mState != WGuiFilterItem::STATE_FINISHED) continue;
|
|
switch (type)
|
|
{
|
|
case WGuiFilterItem::FILTER_TYPE:
|
|
case WGuiFilterItem::FILTER_SUBTYPE:
|
|
case WGuiFilterItem::FILTER_BASIC:
|
|
return true;
|
|
case WGuiFilterItem::FILTER_PRODUCE:
|
|
if (wgfi->filterType == type) ma++;
|
|
break;
|
|
case WGuiFilterItem::FILTER_COLOR:
|
|
if (wgfi->filterType == type) colors++;
|
|
break;
|
|
default:
|
|
if (wgfi->filterType == type) return false;
|
|
}
|
|
}
|
|
if (colors >= 5) return false;
|
|
if (ma >= 5) return false;
|
|
return true;
|
|
}
|
|
return false; //For some reason, we don't have any rows?
|
|
}
|
|
|
|
void WGuiFilters::clearArgs()
|
|
{
|
|
tempArgs.clear();
|
|
}
|
|
|
|
void WGuiFilters::addArg(string display, string code)
|
|
{
|
|
if (!subMenu || !isAvailableCode(code)) return;
|
|
subMenu->Add((int) tempArgs.size(), display.c_str());
|
|
tempArgs.push_back(pair<string, string> (display, code));
|
|
}
|
|
|
|
//WGuiFilterItem
|
|
WGuiFilterItem::WGuiFilterItem(WGuiFilters * parent) :
|
|
WGuiItem("Cards...")
|
|
{
|
|
filterType = -1;
|
|
filterVal = -1;
|
|
mState = 0;
|
|
mParent = parent;
|
|
mNew = true;
|
|
}
|
|
|
|
void WGuiFilterItem::updateValue()
|
|
{
|
|
bool delMenu = true;
|
|
char buf_name[512];
|
|
char buf_code[512];
|
|
if (!mParent) return;
|
|
switch (mState)
|
|
{
|
|
case STATE_CANCEL:
|
|
mState = STATE_UNSET;
|
|
break;
|
|
case STATE_FINISHED:
|
|
case STATE_UNSET:
|
|
SAFE_DELETE(mParent->subMenu);
|
|
mState = STATE_CHOOSE_TYPE;
|
|
SAFE_DELETE(mParent->subMenu);
|
|
mParent->subMenu = NEW SimpleMenu(JGE::GetInstance(), WResourceManager::Instance(), -1234, this, Fonts::MENU_FONT, 20, 20, "Filter By...", 6);
|
|
|
|
if (mParent->isAvailable(FILTER_SET))
|
|
{
|
|
mParent->subMenu->Add(FILTER_SET, "Set");
|
|
delMenu = false;
|
|
}
|
|
if (mParent->isAvailable(FILTER_COLOR))
|
|
{
|
|
mParent->subMenu->Add(FILTER_COLOR, "Color");
|
|
delMenu = false;
|
|
}
|
|
if (mParent->isAvailable(FILTER_TYPE))
|
|
{
|
|
mParent->subMenu->Add(FILTER_TYPE, "Type");
|
|
delMenu = false;
|
|
}
|
|
if (mParent->isAvailable(FILTER_SUBTYPE))
|
|
{
|
|
mParent->subMenu->Add(FILTER_SUBTYPE, "Subtype");
|
|
delMenu = false;
|
|
}
|
|
if (mParent->isAvailable(FILTER_RARITY))
|
|
{
|
|
mParent->subMenu->Add(FILTER_RARITY, "Rarity");
|
|
delMenu = false;
|
|
}
|
|
if (mParent->isAvailable(FILTER_CMC))
|
|
{
|
|
mParent->subMenu->Add(FILTER_CMC, "Mana Cost");
|
|
delMenu = false;
|
|
}
|
|
if (mParent->isAvailable(FILTER_BASIC))
|
|
{
|
|
mParent->subMenu->Add(FILTER_BASIC, "Basic Ability");
|
|
delMenu = false;
|
|
}
|
|
if (mParent->isAvailable(FILTER_PRODUCE))
|
|
{
|
|
mParent->subMenu->Add(FILTER_PRODUCE, "Mana Ability");
|
|
delMenu = false;
|
|
}
|
|
if (mParent->isAvailable(FILTER_POWER))
|
|
{
|
|
mParent->subMenu->Add(FILTER_POWER, "Power");
|
|
delMenu = false;
|
|
}
|
|
if (mParent->isAvailable(FILTER_TOUGH))
|
|
{
|
|
mParent->subMenu->Add(FILTER_TOUGH, "Toughness");
|
|
delMenu = false;
|
|
}
|
|
if (mParent->isAvailable(FILTER_ALPHA))
|
|
{
|
|
mParent->subMenu->Add(FILTER_ALPHA, "First Letter");
|
|
delMenu = false;
|
|
}
|
|
if (!mNew) mParent->subMenu->Add(-2, "Remove");
|
|
mParent->subMenu->Add(kCancelMenuID, "Cancel");
|
|
if (delMenu)
|
|
{
|
|
SAFE_DELETE(mParent->subMenu);
|
|
mState = STATE_FINISHED;
|
|
}
|
|
break;
|
|
case STATE_CHOOSE_TYPE:
|
|
SAFE_DELETE(mParent->subMenu);
|
|
mParent->clearArgs();
|
|
mState = STATE_CHOOSE_VAL;
|
|
mParent->subMenu = NEW SimpleMenu(JGE::GetInstance(), WResourceManager::Instance(), -1234, this, Fonts::MAIN_FONT, 20, 20, "Filter:");
|
|
if (filterType == FILTER_TYPE)
|
|
{
|
|
mParent->addArg("Artifact", "t:Artifact;");
|
|
mParent->addArg("Artifact Creature", "t:Artifact;&t:Creature;");
|
|
mParent->addArg("Aura", "t:Aura;");
|
|
mParent->addArg("Basic", "t:Basic;");
|
|
mParent->addArg("Creature", "t:Creature;");
|
|
mParent->addArg("Enchantment", "t:Enchantment;");
|
|
mParent->addArg("Equipment", "t:Equipment;");
|
|
mParent->addArg("Instant", "t:Instant;");
|
|
mParent->addArg("Land", "t:Land;");
|
|
mParent->addArg("Legendary", "t:Legendary;");
|
|
mParent->addArg("Sorcery", "t:Sorcery;");
|
|
mParent->addArg("Tribal", "t:Tribal;");
|
|
mParent->addArg("Planeswalker", "t:Planeswalker;");
|
|
|
|
}
|
|
else if (filterType == FILTER_SUBTYPE)
|
|
{
|
|
vector<string> stlist;
|
|
for (int i = Subtypes::LAST_TYPE + 1;; i++)
|
|
{
|
|
string s = MTGAllCards::findType(i);
|
|
if (s == "") break;
|
|
if (s.find(" ") != string::npos) continue;
|
|
if (s == "Nothing")
|
|
{//dont add "nothing" to the search filters.
|
|
}
|
|
else
|
|
{
|
|
stlist.push_back(s);
|
|
}
|
|
}
|
|
std::sort(stlist.begin(), stlist.end());
|
|
for (size_t t = 0; t < stlist.size(); t++)
|
|
{
|
|
string s = stlist[t];
|
|
char buf[1024];
|
|
sprintf(buf, "t:%s;", s.c_str());
|
|
mParent->addArg(s, buf);
|
|
}
|
|
}
|
|
else if (filterType == FILTER_RARITY)
|
|
{
|
|
mParent->addArg("Mythic", "r:m;");
|
|
mParent->addArg("Rare", "r:r;");
|
|
mParent->addArg("Uncommon", "r:u;");
|
|
mParent->addArg("Common", "r:c;");
|
|
mParent->addArg("Special Rarity", "{r:m;|r:t;|r:r;|r:u;|r:c;|r:l;}");
|
|
}
|
|
else if (filterType == FILTER_CMC)
|
|
{
|
|
for (int i = 0; i < 17; i++)
|
|
{
|
|
sprintf(buf_code, "cmc:%i;", i);
|
|
sprintf(buf_name, "%i Mana", i);
|
|
mParent->addArg(buf_name, buf_code);
|
|
}
|
|
}
|
|
else if (filterType == FILTER_POWER)
|
|
{
|
|
for (int i = 0; i < 17; i++)
|
|
{
|
|
sprintf(buf_code, "pow:%i;", i);
|
|
sprintf(buf_name, "%i power", i);
|
|
mParent->addArg(buf_name, buf_code);
|
|
}
|
|
}
|
|
else if (filterType == FILTER_TOUGH)
|
|
{
|
|
for (int i = 0; i < 18; i++)
|
|
{
|
|
sprintf(buf_code, "tgh:%i;", i);
|
|
sprintf(buf_name, "%i toughness", i);
|
|
mParent->addArg(buf_name, buf_code);
|
|
}
|
|
}
|
|
else if (filterType == FILTER_COLOR)
|
|
{
|
|
mParent->addArg("White", "c:w;");
|
|
mParent->addArg("Blue", "c:u;");
|
|
mParent->addArg("Black", "c:b;");
|
|
mParent->addArg("Red", "c:r;");
|
|
mParent->addArg("Green", "c:g;");
|
|
mParent->addArg("Exclusively White", "xc:w;");
|
|
mParent->addArg("Exclusively Blue", "xc:u;");
|
|
mParent->addArg("Exclusively Black", "xc:b;");
|
|
mParent->addArg("Exclusively Red", "xc:r;");
|
|
mParent->addArg("Exclusively Green", "xc:g;");
|
|
mParent->addArg("Not White", "nc:w;");
|
|
mParent->addArg("Not Blue", "nc:u;");
|
|
mParent->addArg("Not Black", "nc:b;");
|
|
mParent->addArg("Not Red", "nc:r;");
|
|
mParent->addArg("Not Green", "nc:g;");
|
|
mParent->addArg("Not Colorless", "nc:x;");
|
|
mParent->addArg("Only Multicolored", "nc:m;");
|
|
}
|
|
else if (filterType == FILTER_PRODUCE)
|
|
{
|
|
mParent->addArg("White mana abiltity", "ma:w;");
|
|
mParent->addArg("Blue mana abiltity", "ma:u;");
|
|
mParent->addArg("Black mana abiltity", "ma:b;");
|
|
mParent->addArg("Red mana abiltity", "ma:r;");
|
|
mParent->addArg("Green mana abiltity", "ma:g;");
|
|
mParent->addArg("Colorless mana abiltity", "ma:x;");
|
|
}
|
|
else if (filterType == FILTER_BASIC)
|
|
{
|
|
char buf[512];
|
|
vector<string> baString;
|
|
for (int i = 0; i < Constants::NB_BASIC_ABILITIES; i++)
|
|
{//remove some others
|
|
if(i != 119 || i != 120 || i != 135 || i != 136 || i != 137 || i != 139 || i != 140 || i != 141 || i != 143
|
|
|| i != 144 || i != 145 || i != 146 || i != 147 || i != 148 || i != 149 || i != 150
|
|
|| i != 151 || i != 152 || i != 153 || i != 154)
|
|
baString.push_back(Constants::MTGBasicAbilities[i]);
|
|
}
|
|
//sort
|
|
sort(baString.begin(),baString.end());
|
|
for (unsigned int i = 0; i < baString.size(); i++)
|
|
{
|
|
string s = baString[i];
|
|
sprintf(buf, "a:%s;", s.c_str());
|
|
s[0] = toupper(s[0]);
|
|
mParent->addArg(s, buf);
|
|
}
|
|
}
|
|
else if (filterType == FILTER_SET)
|
|
{
|
|
vector<pair<string, string> > orderedSet;
|
|
for(int i = 0; i < setlist.size(); i++){
|
|
if (options[Options::optionSet(i)].number == 0) continue;
|
|
if (options[Options::SORTINGSETS].number == Constants::BY_DATE) // Now sets can be sorted by sector(orderindex) or name or release date.
|
|
orderedSet.push_back(pair<string, string> (setlist.getInfo(i)->getDate(), setlist[i].c_str()));
|
|
else if (options[Options::SORTINGSETS].number == Constants::BY_NAME)
|
|
orderedSet.push_back(pair<string, string> (setlist.getInfo(i)->getName(), setlist[i].c_str()));
|
|
else
|
|
orderedSet.push_back(pair<string, string> (setlist.getInfo(i)->getOrderIndex(), setlist[i].c_str()));
|
|
}
|
|
sort(orderedSet.begin(),orderedSet.end());
|
|
for (unsigned int i = 0; i < orderedSet.size(); i++){
|
|
mParent->addArg(setlist.getInfo(setlist.findSet(orderedSet.at(i).second))->getName(), "s:" + orderedSet.at(i).second + ";");
|
|
}
|
|
}
|
|
else if (filterType == FILTER_ALPHA)
|
|
{
|
|
char buf[24], pretty[16];
|
|
for (char c = 'a'; c <= 'z'; c++)
|
|
{
|
|
sprintf(buf, "alpha:%c;", c);
|
|
sprintf(pretty, "Letter %c", toupper(c));
|
|
mParent->addArg(pretty, buf);
|
|
}
|
|
mParent->addArg("Digit", "alpha:#;");
|
|
}
|
|
mParent->subMenu->Add(kCancelMenuID, "Cancel");
|
|
break;
|
|
case STATE_CHOOSE_VAL:
|
|
mState = STATE_FINISHED;
|
|
if (mNew && mParent) mParent->addColumn();
|
|
mNew = false;
|
|
if (filterVal > -1 && filterVal < (int) mParent->tempArgs.size())
|
|
{
|
|
displayValue = mParent->tempArgs[filterVal].first;
|
|
mCode = mParent->tempArgs[filterVal].second;
|
|
}
|
|
SAFE_DELETE(mParent->subMenu);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void WGuiFilterItem::ButtonPressed(int, int controlId)
|
|
{
|
|
if (!mParent) return;
|
|
|
|
switch (mState)
|
|
{
|
|
case STATE_CHOOSE_TYPE:
|
|
if (controlId == -1)
|
|
{
|
|
mParent->subMenu->Close();
|
|
mState = STATE_CANCEL;
|
|
return;
|
|
}
|
|
else if (controlId == -2)
|
|
{
|
|
mParent->subMenu->Close();
|
|
mState = STATE_REMOVE;
|
|
return;
|
|
}
|
|
filterType = controlId;
|
|
break;
|
|
case STATE_CHOOSE_VAL:
|
|
if (controlId == -1)
|
|
{
|
|
mParent->subMenu->Close();
|
|
mState = STATE_UNSET;
|
|
return;
|
|
}
|
|
else if (controlId == -2)
|
|
{
|
|
mParent->subMenu->Close();
|
|
mState = STATE_REMOVE;
|
|
return;
|
|
}
|
|
filterVal = controlId;
|
|
break;
|
|
}
|
|
updateValue();
|
|
}
|
|
|
|
bool WGuiFilterItem::isModal()
|
|
{
|
|
switch (mState)
|
|
{
|
|
case STATE_UNSET:
|
|
case STATE_REMOVE:
|
|
case STATE_CANCEL:
|
|
case STATE_FINISHED:
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
string WGuiFilterItem::getCode()
|
|
{
|
|
if (mState != STATE_FINISHED || !mCode.size()) return "";
|
|
return mCode;
|
|
}
|
|
|
|
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("")
|
|
{
|
|
populateKeyBindingList();
|
|
}
|
|
|
|
void WGuiKeyBinder::Update(float dt)
|
|
{
|
|
OptionKey* o = dynamic_cast<OptionKey*> (items[1]);
|
|
if (!o) return;
|
|
if (LOCAL_KEY_NONE != o->from)
|
|
{
|
|
items.insert(items.begin() + 1, NEW OptionKey(parent, LOCAL_KEY_NONE, JGE_BTN_NONE));
|
|
if (1 == 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)
|
|
{
|
|
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()
|
|
{
|
|
JGE* j = JGE::GetInstance();
|
|
j->ClearBindings();
|
|
for (vector<WGuiBase*>::iterator it = items.begin(); it != items.end(); ++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();
|
|
}
|
|
|
|
#if (!defined IOS)
|
|
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 };
|
|
#endif
|
|
|
|
#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(JGE::GetInstance(), WResourceManager::Instance(), 0, this, Fonts::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.
|
|
#if (!defined IOS)
|
|
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(JGE::GetInstance(), WResourceManager::Instance(), 1, this, Fonts::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;
|
|
}
|
|
#endif // IOS
|
|
|
|
return CONFIRM_OK;
|
|
}
|
|
|
|
void WGuiKeyBinder::ButtonPressed(int controllerId, int controlId)
|
|
{
|
|
if (1 == controlId)
|
|
{
|
|
confirmed = CONFIRM_CANCEL;
|
|
}
|
|
else if (2 == controlId) {
|
|
switch (controllerId)
|
|
{
|
|
case 0:
|
|
confirmedKeys.insert(confirmingKey);
|
|
break;
|
|
case 1:
|
|
confirmedButtons.insert(confirmingButton);
|
|
break;
|
|
}
|
|
}
|
|
else if (3 == controlId) {
|
|
switch (controllerId)
|
|
{
|
|
case -102:
|
|
JGE::GetInstance()->ResetBindings();
|
|
populateKeyBindingList();
|
|
break;
|
|
}
|
|
}
|
|
SAFE_DELETE(confirmMenu);
|
|
confirmMenu = NULL;
|
|
}
|
|
|
|
void WGuiKeyBinder::Render()
|
|
{
|
|
WGuiList::Render();
|
|
if (confirmMenu)
|
|
{
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
WFont * mFont = WResourceManager::Instance()->GetWFont(Fonts::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;
|
|
float 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;
|
|
}
|
|
|
|
void WGuiKeyBinder::populateKeyBindingList()
|
|
{
|
|
items.clear();
|
|
Add(NEW WGuiButton(NEW WGuiItem("Load Defaults..."), -102, 3, this));
|
|
Add(NEW OptionKey(parent, LOCAL_KEY_NONE, JGE_BTN_NONE));
|
|
|
|
JGE* j = JGE::GetInstance();
|
|
JGE::keybindings_it start = j->KeyBindings_begin(), end = j->KeyBindings_end();
|
|
for (JGE::keybindings_it it = start; it != end; ++it)
|
|
Add(NEW OptionKey(parent, it->first, it->second));
|
|
}
|