2013-12-11 03:23:47 +00:00
|
|
|
#include "SystemView.h"
|
|
|
|
#include "../SystemData.h"
|
|
|
|
#include "../Renderer.h"
|
|
|
|
#include "../Log.h"
|
2013-12-24 17:50:26 +00:00
|
|
|
#include "../Window.h"
|
|
|
|
#include "ViewController.h"
|
2014-02-21 04:20:10 +00:00
|
|
|
#include "../animations/LambdaAnimation.h"
|
|
|
|
#include "../SystemData.h"
|
2013-12-11 03:23:47 +00:00
|
|
|
|
2014-03-01 00:48:11 +00:00
|
|
|
#define SELECTED_SCALE 1.5f
|
|
|
|
#define LOGO_PADDING ((logoSize().x() * (SELECTED_SCALE - 1)/2) + (mSize.x() * 0.06f))
|
2013-12-11 03:23:47 +00:00
|
|
|
|
2014-03-01 21:02:44 +00:00
|
|
|
SystemView::SystemView(Window* window) : IList<SystemViewData, SystemData*>(window, LIST_SCROLL_STYLE_SLOW, LIST_ALWAYS_LOOP)
|
2013-12-11 03:23:47 +00:00
|
|
|
{
|
2014-02-21 04:20:10 +00:00
|
|
|
mCamOffset = 0;
|
2013-12-11 03:23:47 +00:00
|
|
|
|
2014-02-21 04:20:10 +00:00
|
|
|
setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
|
2013-12-11 03:23:47 +00:00
|
|
|
|
2014-02-21 04:20:10 +00:00
|
|
|
populate();
|
2013-12-11 03:23:47 +00:00
|
|
|
}
|
|
|
|
|
2014-02-21 04:20:10 +00:00
|
|
|
void SystemView::populate()
|
2013-12-11 03:23:47 +00:00
|
|
|
{
|
2014-02-21 04:20:10 +00:00
|
|
|
mEntries.clear();
|
2013-12-30 23:23:34 +00:00
|
|
|
|
2014-02-21 04:20:10 +00:00
|
|
|
for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++)
|
|
|
|
{
|
2014-02-25 01:26:58 +00:00
|
|
|
const std::shared_ptr<ThemeData>& theme = (*it)->getTheme();
|
|
|
|
|
2014-02-21 04:20:10 +00:00
|
|
|
Entry e;
|
|
|
|
e.name = (*it)->getName();
|
|
|
|
e.object = *it;
|
2014-01-07 22:57:30 +00:00
|
|
|
|
2014-02-25 01:26:58 +00:00
|
|
|
// make logo
|
|
|
|
if(theme->getElement("system", "header", "image"))
|
2014-02-21 04:20:10 +00:00
|
|
|
{
|
|
|
|
ImageComponent* logo = new ImageComponent(mWindow);
|
|
|
|
logo->setMaxSize(logoSize());
|
|
|
|
logo->applyTheme((*it)->getTheme(), "system", "header", ThemeFlags::PATH);
|
2014-02-27 21:25:30 +00:00
|
|
|
logo->setPosition((logoSize().x() - logo->getSize().x()) / 2, (logoSize().y() - logo->getSize().y()) / 2); // vertically and horizontally center
|
2014-02-21 04:20:10 +00:00
|
|
|
e.data.logo = std::shared_ptr<GuiComponent>(logo);
|
|
|
|
}else{
|
|
|
|
// no logo in theme; use text
|
|
|
|
TextComponent* text = new TextComponent(mWindow);
|
|
|
|
text->setFont(Font::get(FONT_SIZE_LARGE));
|
|
|
|
text->setText((*it)->getName());
|
2014-02-27 21:25:30 +00:00
|
|
|
text->setSize(logoSize().x(), 0);
|
|
|
|
text->setPosition(0, (logoSize().y() - text->getSize().y()) / 2); // vertically center
|
|
|
|
text->setCentered(true); // horizontally center
|
2014-02-21 04:20:10 +00:00
|
|
|
e.data.logo = std::shared_ptr<GuiComponent>(text);
|
|
|
|
}
|
2013-12-30 23:23:34 +00:00
|
|
|
|
2014-02-27 20:20:31 +00:00
|
|
|
// make background extras
|
|
|
|
e.data.backgroundExtras = std::shared_ptr<ThemeExtras>(new ThemeExtras(mWindow));
|
|
|
|
e.data.backgroundExtras->setExtras(ThemeData::makeExtras((*it)->getTheme(), "system", mWindow));
|
2014-02-25 01:26:58 +00:00
|
|
|
|
2014-02-21 04:20:10 +00:00
|
|
|
this->add(e);
|
2013-12-11 03:23:47 +00:00
|
|
|
}
|
2014-02-21 04:20:10 +00:00
|
|
|
}
|
2013-12-11 03:23:47 +00:00
|
|
|
|
2014-02-21 04:20:10 +00:00
|
|
|
void SystemView::goToSystem(SystemData* system)
|
|
|
|
{
|
|
|
|
setCursor(system);
|
2013-12-11 03:23:47 +00:00
|
|
|
}
|
2013-12-24 17:50:26 +00:00
|
|
|
|
|
|
|
bool SystemView::input(InputConfig* config, Input input)
|
|
|
|
{
|
|
|
|
if(input.value != 0)
|
|
|
|
{
|
|
|
|
if(config->isMappedTo("left", input))
|
|
|
|
{
|
2014-02-21 04:20:10 +00:00
|
|
|
listInput(-1);
|
2013-12-24 17:50:26 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(config->isMappedTo("right", input))
|
|
|
|
{
|
2014-02-21 04:20:10 +00:00
|
|
|
listInput(1);
|
2013-12-24 17:50:26 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(config->isMappedTo("a", input))
|
|
|
|
{
|
2014-02-21 04:20:10 +00:00
|
|
|
stopScrolling();
|
|
|
|
mWindow->getViewController()->goToGameList(getSelected());
|
2013-12-24 17:50:26 +00:00
|
|
|
return true;
|
|
|
|
}
|
2014-02-21 04:20:10 +00:00
|
|
|
}else{
|
|
|
|
if(config->isMappedTo("left", input) || config->isMappedTo("right", input))
|
|
|
|
listInput(0);
|
2013-12-24 17:50:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return GuiComponent::input(config, input);
|
|
|
|
}
|
2014-01-25 23:34:29 +00:00
|
|
|
|
2014-02-21 04:20:10 +00:00
|
|
|
void SystemView::update(int deltaTime)
|
|
|
|
{
|
|
|
|
listUpdate(deltaTime);
|
|
|
|
GuiComponent::update(deltaTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SystemView::onCursorChanged(const CursorState& state)
|
|
|
|
{
|
|
|
|
float startPos = mCamOffset;
|
|
|
|
|
2014-02-25 01:26:58 +00:00
|
|
|
float posMax = (float)mEntries.size();
|
|
|
|
float target = (float)mCursor;
|
2014-02-21 04:20:10 +00:00
|
|
|
|
|
|
|
// what's the shortest way to get to our target?
|
|
|
|
// it's one of these...
|
|
|
|
|
|
|
|
float endPos = target; // directly
|
|
|
|
float dist = abs(endPos - startPos);
|
|
|
|
|
|
|
|
if(abs(target + posMax - startPos) < dist)
|
|
|
|
endPos = target + posMax; // loop around the end (0 -> max)
|
|
|
|
if(abs(target - posMax - startPos) < dist)
|
|
|
|
endPos = target - posMax; // loop around the start (max - 1 -> -1)
|
|
|
|
|
|
|
|
Animation* anim = new LambdaAnimation(
|
|
|
|
[startPos, endPos, posMax, this] (float t)
|
|
|
|
{
|
|
|
|
t -= 1;
|
|
|
|
float f = lerp<float>(startPos, endPos, t*t*t + 1);
|
|
|
|
if(f < 0)
|
|
|
|
f += posMax;
|
|
|
|
if(f >= posMax)
|
|
|
|
f -= posMax;
|
|
|
|
this->mCamOffset = f;
|
2014-02-25 01:26:58 +00:00
|
|
|
}, 500);
|
2014-02-21 04:20:10 +00:00
|
|
|
|
|
|
|
setAnimation(anim);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SystemView::render(const Eigen::Affine3f& parentTrans)
|
|
|
|
{
|
|
|
|
if(size() == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Eigen::Affine3f trans = getTransform() * parentTrans;
|
|
|
|
|
2014-02-25 01:26:58 +00:00
|
|
|
// draw the list elements (titles, backgrounds, logos)
|
|
|
|
const float logoSizeX = logoSize().x() + LOGO_PADDING;
|
2014-02-21 04:20:10 +00:00
|
|
|
|
2014-02-25 01:26:58 +00:00
|
|
|
int logoCount = (int)(mSize.x() / logoSizeX) + 2; // how many logos we need to draw
|
|
|
|
int center = (int)(mCamOffset);
|
2014-02-21 04:20:10 +00:00
|
|
|
|
2014-02-27 20:20:31 +00:00
|
|
|
// draw background extras
|
|
|
|
Eigen::Affine3f extrasTrans = trans;
|
2014-02-25 01:26:58 +00:00
|
|
|
for(int i = center - 1; i < center + 2; i++)
|
2014-02-21 04:20:10 +00:00
|
|
|
{
|
2014-02-25 01:26:58 +00:00
|
|
|
int index = i;
|
|
|
|
while(index < 0)
|
|
|
|
index += mEntries.size();
|
|
|
|
while(index >= (int)mEntries.size())
|
|
|
|
index -= mEntries.size();
|
|
|
|
|
2014-02-27 20:20:31 +00:00
|
|
|
extrasTrans.translation() = trans.translation() + Eigen::Vector3f((i - mCamOffset) * mSize.x(), 0, 0);
|
2014-02-25 01:26:58 +00:00
|
|
|
|
2014-02-27 20:20:31 +00:00
|
|
|
mEntries.at(index).data.backgroundExtras->render(extrasTrans);
|
2014-02-21 04:20:10 +00:00
|
|
|
}
|
|
|
|
|
2014-02-25 01:26:58 +00:00
|
|
|
// draw logos
|
|
|
|
float xOff = (mSize.x() - logoSize().x())/2 - (mCamOffset * logoSizeX);
|
|
|
|
float yOff = (mSize.y() - logoSize().y())/2;
|
|
|
|
|
2014-02-27 21:25:30 +00:00
|
|
|
// background behind the logos
|
|
|
|
Renderer::setMatrix(trans);
|
2014-03-01 00:48:11 +00:00
|
|
|
Renderer::drawRect(0, (int)(yOff - (logoSize().y() * (SELECTED_SCALE - 1)) / 2),
|
|
|
|
(int)mSize.x(), (int)(logoSize().y() * SELECTED_SCALE), 0xDDDDDDD8);
|
2014-02-27 21:25:30 +00:00
|
|
|
|
2014-03-01 00:48:11 +00:00
|
|
|
Eigen::Affine3f logoTrans = trans;
|
2014-02-27 21:25:30 +00:00
|
|
|
for(int i = center - logoCount/2; i < center + logoCount/2 + 1; i++)
|
2014-02-21 04:20:10 +00:00
|
|
|
{
|
|
|
|
int index = i;
|
|
|
|
while(index < 0)
|
|
|
|
index += mEntries.size();
|
|
|
|
while(index >= (int)mEntries.size())
|
|
|
|
index -= mEntries.size();
|
|
|
|
|
|
|
|
logoTrans.translation() = trans.translation() + Eigen::Vector3f(i * logoSizeX + xOff, yOff, 0);
|
|
|
|
|
|
|
|
std::shared_ptr<GuiComponent> comp = mEntries.at(index).data.logo;
|
|
|
|
if(comp)
|
|
|
|
{
|
2014-02-25 01:26:58 +00:00
|
|
|
if(index == mCursor) //scale our selection up
|
2014-02-21 04:20:10 +00:00
|
|
|
{
|
2014-03-01 00:48:11 +00:00
|
|
|
comp->setOpacity(0xFF);
|
|
|
|
|
2014-02-21 04:20:10 +00:00
|
|
|
// fix the centering because we go by left corner and not center (bleh)
|
2014-03-01 00:48:11 +00:00
|
|
|
// CAN SOMEONE WHO ACTUALLY UNDERSTANDS MATRICES GIVE AN ACTUAL IMPLEMENTATION OF THIS THAT ACTUALLY WORKS?
|
|
|
|
logoTrans.translation() -= Eigen::Vector3f(((comp->getSize().x() + comp->getPosition().x()) * (1/SELECTED_SCALE)) / 2,
|
|
|
|
((comp->getSize().y() + comp->getPosition().y()) * (1/SELECTED_SCALE)) / 2, 0);
|
|
|
|
|
2014-02-21 04:20:10 +00:00
|
|
|
logoTrans.scale(Eigen::Vector3f(SELECTED_SCALE, SELECTED_SCALE, 1.0f));
|
|
|
|
mEntries.at(index).data.logo->render(logoTrans);
|
|
|
|
logoTrans.scale(Eigen::Vector3f(1/SELECTED_SCALE, 1/SELECTED_SCALE, 1.0f));
|
|
|
|
}else{
|
2014-03-01 00:48:11 +00:00
|
|
|
comp->setOpacity(0x80);
|
2014-02-21 04:20:10 +00:00
|
|
|
mEntries.at(index).data.logo->render(logoTrans);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-25 23:34:29 +00:00
|
|
|
std::vector<HelpPrompt> SystemView::getHelpPrompts()
|
|
|
|
{
|
|
|
|
std::vector<HelpPrompt> prompts;
|
2014-02-21 04:20:10 +00:00
|
|
|
prompts.push_back(HelpPrompt("left/right", "choose"));
|
2014-01-25 23:34:29 +00:00
|
|
|
prompts.push_back(HelpPrompt("a", "select"));
|
|
|
|
return prompts;
|
|
|
|
}
|