Commit fcb8623b authored by Aloshi's avatar Aloshi

First form of the new system select carousel.

parent 2886e8e8
......@@ -308,12 +308,8 @@ Reference
---
#### system
* `text name="headerText"` - ALL
- A header text, which displays the name of the system. Displayed at the top center of the screen. Centered by default.
* `image name="header"` - ALL
- A header image. If a non-empty `path` is specified, `text name="headerText"` will be hidden and this image will be, by default, displayed roughly in its place.
* image name="system" - ALL
- A large image representing the system (usually a picture of the system itself).
* `image name="header"` - PATH
- A header (logo) image, to be displayed in the system carousel.
---
......
......@@ -4,58 +4,57 @@
#include "../Log.h"
#include "../Window.h"
#include "ViewController.h"
#include "../animations/LambdaAnimation.h"
#include "../SystemData.h"
SystemView::SystemView(Window* window, SystemData* system) : GuiComponent(window),
mSystem(system),
#define SELECTED_SCALE 1.2f
#define LOGO_PADDING (logoSize().x() * (SELECTED_SCALE - 1)/2)
mHeaderImage(window),
mHeaderText(window),
mImage(window),
mExtras(window)
SystemView::SystemView(Window* window) : IList<SystemViewData, SystemData*>(window)
{
setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
mHeaderImage.setOrigin(0.5f, 0.0f);
mHeaderImage.setPosition(mSize.x() / 2, 0);
mHeaderImage.setResize(0, mSize.y() * 0.2f);
mCamOffset = 0;
mHeaderText.setPosition(0, 6);
mHeaderText.setSize(mSize.x(), 0);
mHeaderText.setCentered(true);
mImage.setOrigin(0.5f, 0.5f);
mImage.setPosition(mSize.x() / 2, mSize.y() * 0.6f);
mImage.setResize(0, mSize.y() * 0.8f);
setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
addChild(&mExtras);
addChild(&mImage);
addChild(&mHeaderText);
addChild(&mHeaderImage);
updateData();
populate();
}
void SystemView::updateData()
void SystemView::populate()
{
using namespace ThemeFlags;
mEntries.clear();
mExtras.setExtras(ThemeData::makeExtras(mSystem->getTheme(), "system", mWindow));
for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++)
{
Entry e;
e.name = (*it)->getName();
e.object = *it;
mHeaderImage.setImage("");
mHeaderImage.applyTheme(mSystem->getTheme(), "system", "header", ALL);
if((*it)->getTheme()->getElement("system", "header", "image"))
{
ImageComponent* logo = new ImageComponent(mWindow);
logo->setMaxSize(logoSize());
logo->applyTheme((*it)->getTheme(), "system", "header", ThemeFlags::PATH);
logo->setPosition((logoSize().x() - logo->getSize().x()) / 2, 0);
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());
text->setSize(logoSize());
text->setCentered(true);
e.data.logo = std::shared_ptr<GuiComponent>(text);
}
// header
if(mHeaderImage.hasImage())
{
// use image
mHeaderText.setText("");
}else{
// use text
mHeaderImage.setImage("");
mHeaderText.setText(mSystem->getFullName());
e.data.title = nullptr;
this->add(e);
}
}
mImage.applyTheme(mSystem->getTheme(), "system", "system", ALL);
void SystemView::goToSystem(SystemData* system)
{
setCursor(system);
}
bool SystemView::input(InputConfig* config, Input input)
......@@ -64,27 +63,129 @@ bool SystemView::input(InputConfig* config, Input input)
{
if(config->isMappedTo("left", input))
{
mWindow->getViewController()->goToSystemView(mSystem->getPrev());
listInput(-1);
return true;
}
if(config->isMappedTo("right", input))
{
mWindow->getViewController()->goToSystemView(mSystem->getNext());
listInput(1);
return true;
}
if(config->isMappedTo("a", input))
{
mWindow->getViewController()->goToGameList(mSystem);
stopScrolling();
mWindow->getViewController()->goToGameList(getSelected());
return true;
}
}else{
if(config->isMappedTo("left", input) || config->isMappedTo("right", input))
listInput(0);
}
return GuiComponent::input(config, input);
}
void SystemView::update(int deltaTime)
{
listUpdate(deltaTime);
GuiComponent::update(deltaTime);
}
void SystemView::onCursorChanged(const CursorState& state)
{
float startPos = mCamOffset;
const float logoSizeX = logoSize().x() + LOGO_PADDING;
float posMax = logoSizeX * mEntries.size();
float target = mCursor * logoSizeX;
// 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;
}, 400);
setAnimation(anim);
}
void SystemView::render(const Eigen::Affine3f& parentTrans)
{
if(size() == 0)
return;
const float logoSizeX = logoSize().x() + LOGO_PADDING;
Eigen::Affine3f trans = getTransform() * parentTrans;
// draw background image
// draw system's stats
// now for the list elements (logos)
Eigen::Affine3f logoTrans = trans;
int logoCount = (int)(mSize.x() / logoSizeX) + 2; // how many logos we need to draw
int center = (int)(mCamOffset / logoSizeX + 0.5f);
float xOff = (mSize.x() - logoSize().x())/2 - mCamOffset;
float yOff = (mSize.y() - logoSize().y())/2;
// this fixes the case where i != mCursor when wrapping around the end back to zero
while(center >= (int)mEntries.size())
{
center -= mEntries.size();
xOff += logoSizeX * mEntries.size();
}
for(int i = center - logoCount/2; i < center + logoCount/2 + logoCount%2; i++)
{
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)
{
if(i == mCursor) //scale our selection up
{
// fix the centering because we go by left corner and not center (bleh)
logoTrans.translation() -= Eigen::Vector3f((comp->getSize().x() / 2) * (SELECTED_SCALE - 1), (comp->getSize().y() / 2) * (SELECTED_SCALE - 1), 0);
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{
mEntries.at(index).data.logo->render(logoTrans);
}
}
}
}
std::vector<HelpPrompt> SystemView::getHelpPrompts()
{
std::vector<HelpPrompt> prompts;
prompts.push_back(HelpPrompt("left/right", "choose"));
prompts.push_back(HelpPrompt("a", "select"));
return prompts;
}
......@@ -4,25 +4,37 @@
#include "../components/ImageComponent.h"
#include "../components/TextComponent.h"
#include "../components/ScrollableContainer.h"
#include "../components/IList.h"
#include "../resources/TextureResource.h"
class SystemData;
class SystemView : public GuiComponent
struct SystemViewData
{
std::shared_ptr<TextCache> title;
std::shared_ptr<GuiComponent> logo;
};
class SystemView : public IList<SystemViewData, SystemData*>
{
public:
SystemView(Window* window, SystemData* system);
SystemView(Window* window);
void updateData();
void goToSystem(SystemData* system);
bool input(InputConfig* config, Input input) override;
void update(int deltaTime) override;
void render(const Eigen::Affine3f& parentTrans) override;
std::vector<HelpPrompt> getHelpPrompts() override;
protected:
void onCursorChanged(const CursorState& state) override;
private:
SystemData* mSystem;
inline Eigen::Vector2f logoSize() const { return Eigen::Vector2f(mSize.x() * 0.3f, mSize.y() * 0.25f); }
void populate();
TextComponent mHeaderText;
ImageComponent mHeaderImage;
ImageComponent mImage;
ThemeExtras mExtras;
float mCamOffset;
};
......@@ -30,7 +30,10 @@ void ViewController::goToStart()
void ViewController::goToSystemView(SystemData* system)
{
mState.viewing = SYSTEM_SELECT;
mCurrentView = getSystemView(system);
mState.system = system;
getSystemListView()->goToSystem(system);
mCurrentView = getSystemListView();
updateHelpPrompts();
playViewTransition();
}
......@@ -54,7 +57,7 @@ void ViewController::goToPrevGameList()
void ViewController::goToGameList(SystemData* system)
{
mState.viewing = GAME_LIST;
mState.data.system = system;
mState.system = system;
mCurrentView = getGameListView(system);
updateHelpPrompts();
......@@ -140,18 +143,15 @@ std::shared_ptr<IGameListView> ViewController::getGameListView(SystemData* syste
return view;
}
std::shared_ptr<SystemView> ViewController::getSystemView(SystemData* system)
std::shared_ptr<SystemView> ViewController::getSystemListView()
{
//if we already made one, return that one
auto exists = mSystemViews.find(system);
if(exists != mSystemViews.end())
return exists->second;
if(mSystemListView)
return mSystemListView;
//if we didn't, make it, remember it, and return it
std::shared_ptr<SystemView> view = std::shared_ptr<SystemView>(new SystemView(mWindow, system));
view->setPosition((system->getIterator() - SystemData::sSystemVector.begin()) * (float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
mSystemViews[system] = view;
return view;
mSystemListView = std::shared_ptr<SystemView>(new SystemView(mWindow));
mSystemListView->setPosition(0, (float)Renderer::getScreenHeight());
return mSystemListView;
}
......@@ -192,13 +192,9 @@ void ViewController::render(const Eigen::Affine3f& parentTrans)
Eigen::Vector3f viewStart = trans.inverse().translation();
Eigen::Vector3f viewEnd = trans.inverse() * Eigen::Vector3f((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight(), 0);
// draw systemviews
for(auto it = mSystemViews.begin(); it != mSystemViews.end(); it++)
{
// should do clipping
it->second->render(trans);
}
// draw systemview
getSystemListView()->render(trans);
// draw gamelists
for(auto it = mGameListViews.begin(); it != mGameListViews.end(); it++)
{
......@@ -223,7 +219,6 @@ void ViewController::preload()
{
for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++)
{
getSystemView(*it);
getGameListView(*it);
}
}
......
......@@ -48,14 +48,11 @@ public:
{
ViewMode viewing;
inline SystemData* getSystem() const { assert(viewing == GAME_LIST); return data.system; }
inline SystemData* getSystem() const { assert(viewing == GAME_LIST || viewing == SYSTEM_SELECT); return system; }
private:
friend ViewController;
union
{
SystemData* system;
} data;
SystemData* system;
};
inline const State& getState() const { return mState; }
......@@ -65,11 +62,11 @@ public:
private:
void playViewTransition();
std::shared_ptr<IGameListView> getGameListView(SystemData* system);
std::shared_ptr<SystemView> getSystemView(SystemData* system);
std::shared_ptr<SystemView> getSystemListView();
std::shared_ptr<GuiComponent> mCurrentView;
std::map< SystemData*, std::shared_ptr<IGameListView> > mGameListViews;
std::map< SystemData*, std::shared_ptr<SystemView> > mSystemViews;
std::shared_ptr<SystemView> mSystemListView;
Eigen::Affine3f mCamera;
float mFadeOpacity;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment