2013-11-25 20:49:02 +00:00
|
|
|
#include "GuiFastSelect.h"
|
|
|
|
#include "../ThemeData.h"
|
|
|
|
#include "../FileSorts.h"
|
|
|
|
#include "../SystemData.h"
|
|
|
|
|
|
|
|
static const std::string LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
|
|
|
|
|
|
GuiFastSelect::GuiFastSelect(Window* window, GameListView* gamelist) : GuiComponent(window),
|
2013-11-28 19:52:21 +00:00
|
|
|
mBackground(window), mSortText(window), mLetterText(window), mGameList(gamelist)
|
2013-11-25 20:49:02 +00:00
|
|
|
{
|
|
|
|
setPosition(Renderer::getScreenWidth() * 0.2f, Renderer::getScreenHeight() * 0.2f);
|
|
|
|
setSize(Renderer::getScreenWidth() * 0.6f, Renderer::getScreenHeight() * 0.6f);
|
|
|
|
|
|
|
|
const std::shared_ptr<ThemeData>& theme = mGameList->getTheme();
|
|
|
|
|
2013-11-28 19:52:21 +00:00
|
|
|
mBackground.setImagePath(theme->getImage("fastSelectBackgroundImage").path);
|
2013-11-25 20:49:02 +00:00
|
|
|
mBackground.fitTo(mSize);
|
|
|
|
addChild(&mBackground);
|
|
|
|
|
|
|
|
mLetterText.setSize(mSize.x(), mSize.y() * 0.75f);
|
|
|
|
mLetterText.setCentered(true);
|
|
|
|
mLetterText.setFromTheme(theme, "fastSelectLetterFont", "fastSelectLetterColor");
|
|
|
|
addChild(&mLetterText);
|
|
|
|
|
|
|
|
mSortText.setPosition(0, mSize.y() * 0.75f);
|
|
|
|
mSortText.setSize(mSize.x(), mSize.y() * 0.25f);
|
|
|
|
mSortText.setCentered(true);
|
|
|
|
mSortText.setFromTheme(theme, "descriptionFont", "fastSelectTextColor");
|
|
|
|
addChild(&mSortText);
|
|
|
|
|
|
|
|
mSortId = 0; // TODO
|
|
|
|
updateSortText();
|
|
|
|
|
|
|
|
mLetterId = LETTERS.find(mGameList->getCursor()->getName()[0]);
|
|
|
|
if(mLetterId == std::string::npos)
|
|
|
|
mLetterId = 0;
|
|
|
|
|
|
|
|
mScrollDir = 0;
|
|
|
|
mScrollAccumulator = 0;
|
|
|
|
scroll(); // initialize the letter value
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GuiFastSelect::input(InputConfig* config, Input input)
|
|
|
|
{
|
|
|
|
if(input.value == 0 && config->isMappedTo("select", input))
|
|
|
|
{
|
|
|
|
// the user let go of select; make our changes to the gamelist and close this gui
|
|
|
|
updateGameListSort();
|
|
|
|
updateGameListCursor();
|
|
|
|
delete this;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(config->isMappedTo("up", input))
|
|
|
|
{
|
|
|
|
if(input.value != 0)
|
|
|
|
setScrollDir(-1);
|
|
|
|
else
|
|
|
|
setScrollDir(0);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}else if(config->isMappedTo("down", input))
|
|
|
|
{
|
|
|
|
if(input.value != 0)
|
|
|
|
setScrollDir(1);
|
|
|
|
else
|
|
|
|
setScrollDir(0);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}else if(config->isMappedTo("left", input) && input.value != 0)
|
|
|
|
{
|
|
|
|
mSortId = (mSortId + 1) % FileSorts::SortTypes.size();
|
|
|
|
updateSortText();
|
|
|
|
return true;
|
|
|
|
}else if(config->isMappedTo("right", input) && input.value != 0)
|
|
|
|
{
|
|
|
|
mSortId--;
|
|
|
|
if(mSortId < 0)
|
|
|
|
mSortId += FileSorts::SortTypes.size();
|
|
|
|
|
|
|
|
updateSortText();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return GuiComponent::input(config, input);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiFastSelect::setScrollDir(int dir)
|
|
|
|
{
|
|
|
|
mScrollDir = dir;
|
|
|
|
scroll();
|
|
|
|
mScrollAccumulator = -500;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiFastSelect::update(int deltaTime)
|
|
|
|
{
|
|
|
|
if(mScrollDir != 0)
|
|
|
|
{
|
|
|
|
mScrollAccumulator += deltaTime;
|
|
|
|
while(mScrollAccumulator >= 150)
|
|
|
|
{
|
|
|
|
scroll();
|
|
|
|
mScrollAccumulator -= 150;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GuiComponent::update(deltaTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiFastSelect::scroll()
|
|
|
|
{
|
|
|
|
mLetterId += mScrollDir;
|
|
|
|
if(mLetterId < 0)
|
|
|
|
mLetterId += LETTERS.length();
|
|
|
|
else if(mLetterId >= (int)LETTERS.length())
|
|
|
|
mLetterId -= LETTERS.length();
|
|
|
|
|
|
|
|
mLetterText.setText(LETTERS.substr(mLetterId, 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiFastSelect::updateSortText()
|
|
|
|
{
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << "<- " << FileSorts::SortTypes.at(mSortId).description << " ->";
|
|
|
|
mSortText.setText(ss.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiFastSelect::updateGameListSort()
|
|
|
|
{
|
|
|
|
const FileData::SortType& sort = FileSorts::SortTypes.at(mSortId);
|
|
|
|
|
|
|
|
FileData* root = mGameList->getCursor()->getSystem()->getRootFolder();
|
|
|
|
root->sort(sort); // will also recursively sort children
|
|
|
|
|
|
|
|
// notify that the root folder was sorted
|
|
|
|
mGameList->onFileChanged(root, FILE_SORTED);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiFastSelect::updateGameListCursor()
|
|
|
|
{
|
|
|
|
const std::vector<FileData*>& list = mGameList->getCursor()->getParent()->getChildren();
|
|
|
|
|
|
|
|
// only skip by letter when the sort mode is alphabetical
|
|
|
|
const FileData::SortType& sort = FileSorts::SortTypes.at(mSortId);
|
|
|
|
if(sort.comparisonFunction != &FileSorts::compareFileName)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// find the first entry in the list that either exactly matches our target letter or is beyond our target letter
|
|
|
|
for(auto it = list.cbegin(); it != list.cend(); it++)
|
|
|
|
{
|
|
|
|
char check = (*it)->getName().empty() ? 'A' : (*it)->getName()[0];
|
|
|
|
|
|
|
|
// if there's an exact match or we've passed it, set the cursor to this one
|
|
|
|
if(check == LETTERS[mLetterId] || (sort.ascending && check > LETTERS[mLetterId]) || (!sort.ascending && check < LETTERS[mLetterId]))
|
|
|
|
{
|
|
|
|
mGameList->setCursor(*it);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|