First form of the new system select carousel.

This commit is contained in:
Aloshi 2014-02-20 22:20:10 -06:00
parent 2886e8e8d8
commit fcb8623b3d
5 changed files with 185 additions and 84 deletions

View file

@ -308,12 +308,8 @@ Reference
--- ---
#### system #### system
* `text name="headerText"` - ALL * `image name="header"` - PATH
- A header text, which displays the name of the system. Displayed at the top center of the screen. Centered by default. - A header (logo) image, to be displayed in the system carousel.
* `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).
--- ---

View file

@ -4,58 +4,57 @@
#include "../Log.h" #include "../Log.h"
#include "../Window.h" #include "../Window.h"
#include "ViewController.h" #include "ViewController.h"
#include "../animations/LambdaAnimation.h"
#include "../SystemData.h"
SystemView::SystemView(Window* window, SystemData* system) : GuiComponent(window), #define SELECTED_SCALE 1.2f
mSystem(system), #define LOGO_PADDING (logoSize().x() * (SELECTED_SCALE - 1)/2)
mHeaderImage(window), SystemView::SystemView(Window* window) : IList<SystemViewData, SystemData*>(window)
mHeaderText(window),
mImage(window),
mExtras(window)
{ {
mCamOffset = 0;
setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight()); setSize((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight());
mHeaderImage.setOrigin(0.5f, 0.0f); populate();
mHeaderImage.setPosition(mSize.x() / 2, 0);
mHeaderImage.setResize(0, mSize.y() * 0.2f);
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);
addChild(&mExtras);
addChild(&mImage);
addChild(&mHeaderText);
addChild(&mHeaderImage);
updateData();
} }
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++)
mHeaderImage.setImage("");
mHeaderImage.applyTheme(mSystem->getTheme(), "system", "header", ALL);
// header
if(mHeaderImage.hasImage())
{ {
// use image Entry e;
mHeaderText.setText(""); e.name = (*it)->getName();
}else{ e.object = *it;
// use text
mHeaderImage.setImage("");
mHeaderText.setText(mSystem->getFullName());
}
mImage.applyTheme(mSystem->getTheme(), "system", "system", 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);
}
e.data.title = nullptr;
this->add(e);
}
}
void SystemView::goToSystem(SystemData* system)
{
setCursor(system);
} }
bool SystemView::input(InputConfig* config, Input input) bool SystemView::input(InputConfig* config, Input input)
@ -64,27 +63,129 @@ bool SystemView::input(InputConfig* config, Input input)
{ {
if(config->isMappedTo("left", input)) if(config->isMappedTo("left", input))
{ {
mWindow->getViewController()->goToSystemView(mSystem->getPrev()); listInput(-1);
return true; return true;
} }
if(config->isMappedTo("right", input)) if(config->isMappedTo("right", input))
{ {
mWindow->getViewController()->goToSystemView(mSystem->getNext()); listInput(1);
return true; return true;
} }
if(config->isMappedTo("a", input)) if(config->isMappedTo("a", input))
{ {
mWindow->getViewController()->goToGameList(mSystem); stopScrolling();
mWindow->getViewController()->goToGameList(getSelected());
return true; return true;
} }
}else{
if(config->isMappedTo("left", input) || config->isMappedTo("right", input))
listInput(0);
} }
return GuiComponent::input(config, input); 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> SystemView::getHelpPrompts()
{ {
std::vector<HelpPrompt> prompts; std::vector<HelpPrompt> prompts;
prompts.push_back(HelpPrompt("left/right", "choose"));
prompts.push_back(HelpPrompt("a", "select")); prompts.push_back(HelpPrompt("a", "select"));
return prompts; return prompts;
} }

View file

@ -4,25 +4,37 @@
#include "../components/ImageComponent.h" #include "../components/ImageComponent.h"
#include "../components/TextComponent.h" #include "../components/TextComponent.h"
#include "../components/ScrollableContainer.h" #include "../components/ScrollableContainer.h"
#include "../components/IList.h"
#include "../resources/TextureResource.h"
class SystemData; 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: public:
SystemView(Window* window, SystemData* system); SystemView(Window* window);
void updateData(); void goToSystem(SystemData* system);
bool input(InputConfig* config, Input input) override; bool input(InputConfig* config, Input input) override;
void update(int deltaTime) override;
void render(const Eigen::Affine3f& parentTrans) override;
std::vector<HelpPrompt> getHelpPrompts() override; std::vector<HelpPrompt> getHelpPrompts() override;
protected:
void onCursorChanged(const CursorState& state) override;
private: private:
SystemData* mSystem; inline Eigen::Vector2f logoSize() const { return Eigen::Vector2f(mSize.x() * 0.3f, mSize.y() * 0.25f); }
TextComponent mHeaderText; void populate();
ImageComponent mHeaderImage;
ImageComponent mImage; float mCamOffset;
ThemeExtras mExtras;
}; };

View file

@ -30,7 +30,10 @@ void ViewController::goToStart()
void ViewController::goToSystemView(SystemData* system) void ViewController::goToSystemView(SystemData* system)
{ {
mState.viewing = SYSTEM_SELECT; mState.viewing = SYSTEM_SELECT;
mCurrentView = getSystemView(system); mState.system = system;
getSystemListView()->goToSystem(system);
mCurrentView = getSystemListView();
updateHelpPrompts(); updateHelpPrompts();
playViewTransition(); playViewTransition();
} }
@ -54,7 +57,7 @@ void ViewController::goToPrevGameList()
void ViewController::goToGameList(SystemData* system) void ViewController::goToGameList(SystemData* system)
{ {
mState.viewing = GAME_LIST; mState.viewing = GAME_LIST;
mState.data.system = system; mState.system = system;
mCurrentView = getGameListView(system); mCurrentView = getGameListView(system);
updateHelpPrompts(); updateHelpPrompts();
@ -140,18 +143,15 @@ std::shared_ptr<IGameListView> ViewController::getGameListView(SystemData* syste
return view; return view;
} }
std::shared_ptr<SystemView> ViewController::getSystemView(SystemData* system) std::shared_ptr<SystemView> ViewController::getSystemListView()
{ {
//if we already made one, return that one //if we already made one, return that one
auto exists = mSystemViews.find(system); if(mSystemListView)
if(exists != mSystemViews.end()) return mSystemListView;
return exists->second;
//if we didn't, make it, remember it, and return it mSystemListView = std::shared_ptr<SystemView>(new SystemView(mWindow));
std::shared_ptr<SystemView> view = std::shared_ptr<SystemView>(new SystemView(mWindow, system)); mSystemListView->setPosition(0, (float)Renderer::getScreenHeight());
view->setPosition((system->getIterator() - SystemData::sSystemVector.begin()) * (float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight()); return mSystemListView;
mSystemViews[system] = view;
return view;
} }
@ -192,13 +192,9 @@ void ViewController::render(const Eigen::Affine3f& parentTrans)
Eigen::Vector3f viewStart = trans.inverse().translation(); Eigen::Vector3f viewStart = trans.inverse().translation();
Eigen::Vector3f viewEnd = trans.inverse() * Eigen::Vector3f((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight(), 0); Eigen::Vector3f viewEnd = trans.inverse() * Eigen::Vector3f((float)Renderer::getScreenWidth(), (float)Renderer::getScreenHeight(), 0);
// draw systemviews // draw systemview
for(auto it = mSystemViews.begin(); it != mSystemViews.end(); it++) getSystemListView()->render(trans);
{
// should do clipping
it->second->render(trans);
}
// draw gamelists // draw gamelists
for(auto it = mGameListViews.begin(); it != mGameListViews.end(); it++) 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++) for(auto it = SystemData::sSystemVector.begin(); it != SystemData::sSystemVector.end(); it++)
{ {
getSystemView(*it);
getGameListView(*it); getGameListView(*it);
} }
} }

View file

@ -48,14 +48,11 @@ public:
{ {
ViewMode viewing; 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: private:
friend ViewController; friend ViewController;
union SystemData* system;
{
SystemData* system;
} data;
}; };
inline const State& getState() const { return mState; } inline const State& getState() const { return mState; }
@ -65,11 +62,11 @@ public:
private: private:
void playViewTransition(); void playViewTransition();
std::shared_ptr<IGameListView> getGameListView(SystemData* system); 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::shared_ptr<GuiComponent> mCurrentView;
std::map< SystemData*, std::shared_ptr<IGameListView> > mGameListViews; std::map< SystemData*, std::shared_ptr<IGameListView> > mGameListViews;
std::map< SystemData*, std::shared_ptr<SystemView> > mSystemViews; std::shared_ptr<SystemView> mSystemListView;
Eigen::Affine3f mCamera; Eigen::Affine3f mCamera;
float mFadeOpacity; float mFadeOpacity;