Merge pull request #212 from jrassa/carousel-enhancements

carousel enhancements
This commit is contained in:
John Rassa 2017-08-19 09:25:52 -04:00 committed by GitHub
commit 230c6e4a97
14 changed files with 223 additions and 87 deletions

View file

@ -673,17 +673,32 @@ EmulationStation borrows the concept of "nine patches" from Android (or "9-Slice
#### carousel #### carousel
* `type` - type: STRING. * `type` - type: STRING.
- Accepted values are "horizontal" or "vertical". Sets the scoll direction of the carousel. - Sets the scoll direction of the carousel.
- Accepted values are "horizontal", "vertical" or "vertical_wheel".
- Default is "horizontal". - Default is "horizontal".
* `size` - type: NORMALIZED_PAIR. Default is "1 0.2325" * `size` - type: NORMALIZED_PAIR. Default is "1 0.2325"
* `pos` - type: NORMALIZED_PAIR. Default is "0 0.38375". * `pos` - type: NORMALIZED_PAIR. Default is "0 0.38375".
* `origin` - type: NORMALIZED_PAIR.
- Where on the carousel `pos` refers to. For example, an origin of `0.5 0.5` and a `pos` of `0.5 0.5` would place the carousel exactly in the middle of the screen. If the "POSITION" and "SIZE" attributes are themable, "ORIGIN" is implied.
* `color` - type: COLOR. * `color` - type: COLOR.
- Controls the color of the carousel background. - Controls the color of the carousel background.
- Default is FFFFFFD8 - Default is FFFFFFD8
* `logoSize` - type: NORMALIZED_PAIR. Default is "0.25 0.155" * `logoSize` - type: NORMALIZED_PAIR. Default is "0.25 0.155"
* `logoScale` - type: FLOAT. * `logoScale` - type: FLOAT.
* Selected logo is increased in size by this scale - Selected logo is increased in size by this scale
* Default is 1.2 - Default is 1.2
* `logoRotation` - type: FLOAT.
- Angle in degrees that the logos should be rotated. Value should be positive.
- Default is 7.5
- This property only applies when `type` is "vertical_wheel".
* `logoRotationOrigin` - type: NORMALIZED_PAIR.
- Point around which the logos will be rotated. Defaults to `-5 0.5`.
- This property only applies when `type` is "vertical_wheel".
* `logoAlignment` - type: STRING.
- Sets the alignment of the logos relative to the carousel.
- Accepted values are "top", "bottom" or "center" when `type` is "horizontal".
- Accepted values are "left", "right" or "center" when `type` is "vertical" or "vertical_wheel".
- Default is "center"
* `maxLogoCount` - type: FLOAT. * `maxLogoCount` - type: FLOAT.
- Sets the number of logos to display in the carousel. - Sets the number of logos to display in the carousel.
- Default is 3 - Default is 3

View file

@ -19,14 +19,14 @@ GuiFastSelect::GuiFastSelect(Window* window, IGameListView* gamelist) : GuiCompo
addChild(&mBackground); addChild(&mBackground);
mLetterText.setSize(mSize.x(), mSize.y() * 0.75f); mLetterText.setSize(mSize.x(), mSize.y() * 0.75f);
mLetterText.setAlignment(ALIGN_CENTER); mLetterText.setHorizontalAlignment(ALIGN_CENTER);
mLetterText.applyTheme(theme, "fastSelect", "letter", FONT_PATH | COLOR); mLetterText.applyTheme(theme, "fastSelect", "letter", FONT_PATH | COLOR);
// TODO - set font size // TODO - set font size
addChild(&mLetterText); addChild(&mLetterText);
mSortText.setPosition(0, mSize.y() * 0.75f); mSortText.setPosition(0, mSize.y() * 0.75f);
mSortText.setSize(mSize.x(), mSize.y() * 0.25f); mSortText.setSize(mSize.x(), mSize.y() * 0.25f);
mSortText.setAlignment(ALIGN_CENTER); mSortText.setHorizontalAlignment(ALIGN_CENTER);
mSortText.applyTheme(theme, "fastSelect", "subtext", FONT_PATH | COLOR); mSortText.applyTheme(theme, "fastSelect", "subtext", FONT_PATH | COLOR);
// TODO - set font size // TODO - set font size
addChild(&mSortText); addChild(&mSortText);

View file

@ -421,7 +421,7 @@ GuiMenu::GuiMenu(Window* window) : GuiComponent(window), mMenu(window, "MAIN MEN
mVersion.setFont(Font::get(FONT_SIZE_SMALL)); mVersion.setFont(Font::get(FONT_SIZE_SMALL));
mVersion.setColor(0x5E5E5EFF); mVersion.setColor(0x5E5E5EFF);
mVersion.setText("EMULATIONSTATION V" + strToUpper(PROGRAM_VERSION_STRING)); mVersion.setText("EMULATIONSTATION V" + strToUpper(PROGRAM_VERSION_STRING));
mVersion.setAlignment(ALIGN_CENTER); mVersion.setHorizontalAlignment(ALIGN_CENTER);
addChild(&mMenu); addChild(&mMenu);
addChild(&mVersion); addChild(&mVersion);

View file

@ -49,18 +49,10 @@ void SystemView::populate()
if(!path.empty() && ResourceManager::getInstance()->fileExists(path)) if(!path.empty() && ResourceManager::getInstance()->fileExists(path))
{ {
ImageComponent* logo = new ImageComponent(mWindow, false, false); ImageComponent* logo = new ImageComponent(mWindow, false, false);
logo->setMaxSize(Eigen::Vector2f(mCarousel.logoSize.x(), mCarousel.logoSize.y())); logo->setMaxSize(mCarousel.logoSize * mCarousel.logoScale);
logo->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR); logo->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR);
logo->setPosition((mCarousel.logoSize.x() - logo->getSize().x()) / 2,
(mCarousel.logoSize.y() - logo->getSize().y()) / 2); // center
e.data.logo = std::shared_ptr<GuiComponent>(logo);
ImageComponent* logoSelected = new ImageComponent(mWindow, false, false); e.data.logo = std::shared_ptr<GuiComponent>(logo);
logoSelected->setMaxSize(Eigen::Vector2f(mCarousel.logoSize.x() * mCarousel.logoScale, mCarousel.logoSize.y() * mCarousel.logoScale));
logoSelected->applyTheme((*it)->getTheme(), "system", "logo", ThemeFlags::PATH | ThemeFlags::COLOR);
logoSelected->setPosition((mCarousel.logoSize.x() - logoSelected->getSize().x()) / 2,
(mCarousel.logoSize.y() - logoSelected->getSize().y()) / 2); // center
e.data.logoSelected = std::shared_ptr<GuiComponent>(logoSelected);
} }
} }
if (!e.data.logo) if (!e.data.logo)
@ -71,20 +63,36 @@ void SystemView::populate()
Font::get(FONT_SIZE_LARGE), Font::get(FONT_SIZE_LARGE),
0x000000FF, 0x000000FF,
ALIGN_CENTER); ALIGN_CENTER);
text->setSize(mCarousel.logoSize); text->setSize(mCarousel.logoSize * mCarousel.logoScale);
text->applyTheme((*it)->getTheme(), "system", "logoText", ThemeFlags::FONT_PATH | ThemeFlags::COLOR | ThemeFlags::FORCE_UPPERCASE); text->applyTheme((*it)->getTheme(), "system", "logoText", ThemeFlags::FONT_PATH | ThemeFlags::FONT_SIZE | ThemeFlags::COLOR | ThemeFlags::FORCE_UPPERCASE);
e.data.logo = std::shared_ptr<GuiComponent>(text); e.data.logo = std::shared_ptr<GuiComponent>(text);
TextComponent* textSelected = new TextComponent(mWindow, if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL)
(*it)->getName(), text->setHorizontalAlignment(mCarousel.logoAlignment);
Font::get((int)(FONT_SIZE_LARGE * mCarousel.logoScale)), else
0x000000FF, text->setVerticalAlignment(mCarousel.logoAlignment);
ALIGN_CENTER);
textSelected->setSize(mCarousel.logoSize);
textSelected->applyTheme((*it)->getTheme(), "system", "logoText", ThemeFlags::FONT_PATH | ThemeFlags::COLOR | ThemeFlags::FORCE_UPPERCASE);
e.data.logoSelected = std::shared_ptr<GuiComponent>(textSelected);
} }
if (mCarousel.type == VERTICAL || mCarousel.type == VERTICAL_WHEEL)
{
if (mCarousel.logoAlignment == ALIGN_LEFT)
e.data.logo->setOrigin(0, 0.5);
else if (mCarousel.logoAlignment == ALIGN_RIGHT)
e.data.logo->setOrigin(1.0, 0.5);
else
e.data.logo->setOrigin(0.5, 0.5);
} else {
if (mCarousel.logoAlignment == ALIGN_TOP)
e.data.logo->setOrigin(0.5, 0);
else if (mCarousel.logoAlignment == ALIGN_BOTTOM)
e.data.logo->setOrigin(0.5, 1);
else
e.data.logo->setOrigin(0.5, 0.5);
}
Eigen::Vector2f denormalized = mCarousel.logoSize.cwiseProduct(e.data.logo->getOrigin());
e.data.logo->setPosition(denormalized.x(), denormalized.y(), 0.0);
// delete any existing extras // delete any existing extras
for (auto extra : e.data.backgroundExtras) for (auto extra : e.data.backgroundExtras)
delete extra; delete extra;
@ -94,7 +102,7 @@ void SystemView::populate()
e.data.backgroundExtras = ThemeData::makeExtras((*it)->getTheme(), "system", mWindow); e.data.backgroundExtras = ThemeData::makeExtras((*it)->getTheme(), "system", mWindow);
// sort the extras by z-index // sort the extras by z-index
std:stable_sort(e.data.backgroundExtras.begin(), e.data.backgroundExtras.end(), [](GuiComponent* a, GuiComponent* b) { std::stable_sort(e.data.backgroundExtras.begin(), e.data.backgroundExtras.end(), [](GuiComponent* a, GuiComponent* b) {
return b->getZIndex() > a->getZIndex(); return b->getZIndex() > a->getZIndex();
}); });
@ -124,6 +132,7 @@ bool SystemView::input(InputConfig* config, Input input)
switch (mCarousel.type) switch (mCarousel.type)
{ {
case VERTICAL: case VERTICAL:
case VERTICAL_WHEEL:
if (config->isMappedTo("up", input)) if (config->isMappedTo("up", input))
{ {
listInput(-1); listInput(-1);
@ -400,14 +409,16 @@ void SystemView::getViewElements(const std::shared_ptr<ThemeData>& theme)
// Render system carousel // Render system carousel
void SystemView::renderCarousel(const Eigen::Affine3f& trans) void SystemView::renderCarousel(const Eigen::Affine3f& trans)
{ {
Eigen::Vector2i clipPos((int)mCarousel.pos.x(), (int)mCarousel.pos.y());
Eigen::Vector2i clipSize((int)mCarousel.size.x(), (int)mCarousel.size.y());
Renderer::pushClipRect(clipPos, clipSize);
// background box behind logos // background box behind logos
Renderer::setMatrix(trans); Eigen::Affine3f carouselTrans = trans;
Renderer::drawRect(mCarousel.pos.x(), mCarousel.pos.y(), mCarousel.size.x(), mCarousel.size.y(), mCarousel.color); carouselTrans.translate(Eigen::Vector3f(mCarousel.pos.x(), mCarousel.pos.y(), 0.0));
carouselTrans.translate(Eigen::Vector3f(mCarousel.origin.x() * mCarousel.size.x() * -1, mCarousel.origin.y() * mCarousel.size.y() * -1, 0.0f));
Eigen::Vector2f clipPos(carouselTrans.translation().x(), carouselTrans.translation().y());
Renderer::pushClipRect(clipPos.cast<int>(), mCarousel.size.cast<int>());
Renderer::setMatrix(carouselTrans);
Renderer::drawRect(0.0, 0.0, mCarousel.size.x(), mCarousel.size.y(), mCarousel.color);
// draw logos // draw logos
Eigen::Vector2f logoSpacing(0.0, 0.0); // NB: logoSpacing will include the size of the logo itself as well! Eigen::Vector2f logoSpacing(0.0, 0.0); // NB: logoSpacing will include the size of the logo itself as well!
@ -416,20 +427,40 @@ void SystemView::renderCarousel(const Eigen::Affine3f& trans)
switch (mCarousel.type) switch (mCarousel.type)
{ {
case VERTICAL_WHEEL:
yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2 - (mCamOffset * logoSpacing[1]);
if (mCarousel.logoAlignment == ALIGN_LEFT)
xOff = mCarousel.logoSize.x() / 10;
else if (mCarousel.logoAlignment == ALIGN_RIGHT)
xOff = mCarousel.size.x() - (mCarousel.logoSize.x() * 1.1);
else
xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2;
break;
case VERTICAL: case VERTICAL:
logoSpacing[1] = ((mCarousel.size.y() - (mCarousel.logoSize.y() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.y(); logoSpacing[1] = ((mCarousel.size.y() - (mCarousel.logoSize.y() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.y();
xOff = mCarousel.pos.x() + (mCarousel.size.x() / 2) - (mCarousel.logoSize.x() / 2); yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2 - (mCamOffset * logoSpacing[1]);
yOff = mCarousel.pos.y() + (mCarousel.size.y() - mCarousel.logoSize.y()) / 2 - (mCamOffset * logoSpacing[1]);
if (mCarousel.logoAlignment == ALIGN_LEFT)
xOff = mCarousel.logoSize.x() / 10;
else if (mCarousel.logoAlignment == ALIGN_RIGHT)
xOff = mCarousel.size.x() - (mCarousel.logoSize.x() * 1.1);
else
xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2;
break; break;
case HORIZONTAL: case HORIZONTAL:
default: default:
logoSpacing[0] = ((mCarousel.size.x() - (mCarousel.logoSize.x() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.x(); logoSpacing[0] = ((mCarousel.size.x() - (mCarousel.logoSize.x() * mCarousel.maxLogoCount)) / (mCarousel.maxLogoCount)) + mCarousel.logoSize.x();
xOff = mCarousel.pos.x() + (mCarousel.size.x() - mCarousel.logoSize.x()) / 2 - (mCamOffset * logoSpacing[0]); xOff = (mCarousel.size.x() - mCarousel.logoSize.x()) / 2 - (mCamOffset * logoSpacing[0]);
yOff = mCarousel.pos.y() + (mCarousel.size.y() / 2) - (mCarousel.logoSize.y() / 2);
if (mCarousel.logoAlignment == ALIGN_TOP)
yOff = mCarousel.logoSize.y() / 10;
else if (mCarousel.logoAlignment == ALIGN_BOTTOM)
yOff = mCarousel.size.y() - (mCarousel.logoSize.y() * 1.1);
else
yOff = (mCarousel.size.y() - mCarousel.logoSize.y()) / 2;
break; break;
} }
Eigen::Affine3f logoTrans = trans;
int center = (int)(mCamOffset); int center = (int)(mCamOffset);
int logoCount = std::min(mCarousel.maxLogoCount, (int)mEntries.size()); int logoCount = std::min(mCarousel.maxLogoCount, (int)mEntries.size());
@ -444,19 +475,26 @@ void SystemView::renderCarousel(const Eigen::Affine3f& trans)
while (index >= (int)mEntries.size()) while (index >= (int)mEntries.size())
index -= mEntries.size(); index -= mEntries.size();
logoTrans.translation() = trans.translation() + Eigen::Vector3f(i * logoSpacing[0] + xOff, i * logoSpacing [1] + yOff, 0); Eigen::Affine3f logoTrans = carouselTrans;
logoTrans.translate(Eigen::Vector3f(i * logoSpacing[0] + xOff, i * logoSpacing[1] + yOff, 0));
float distance = i - mCamOffset;
float scale = 1.0 + ((mCarousel.logoScale - 1.0) * (1 - fabs(distance)));
scale = std::min(mCarousel.logoScale, std::max(1.0f, scale));
scale /= mCarousel.logoScale;
int opacity = round(0x80 + ((0xFF - 0x80) * (1 - fabs(distance))));
opacity = std::max((int) 0x80, opacity);
if (index == mCursor) //Selected System
{
const std::shared_ptr<GuiComponent>& comp = mEntries.at(index).data.logoSelected;
comp->setOpacity(0xFF);
comp->render(logoTrans);
}
else { // not selected systems
const std::shared_ptr<GuiComponent> &comp = mEntries.at(index).data.logo; const std::shared_ptr<GuiComponent> &comp = mEntries.at(index).data.logo;
comp->setOpacity(0x80); if (mCarousel.type == VERTICAL_WHEEL) {
comp->render(logoTrans); comp->setRotationDegrees(mCarousel.logoRotation * distance);
comp->setRotationOrigin(mCarousel.logoRotationOrigin);
} }
comp->setScale(scale);
comp->setOpacity(opacity);
comp->render(logoTrans);
} }
Renderer::popClipRect(); Renderer::popClipRect();
} }
@ -475,7 +513,7 @@ void SystemView::renderExtras(const Eigen::Affine3f& trans, float lower, float u
// Adding texture loading buffers depending on scrolling speed and status // Adding texture loading buffers depending on scrolling speed and status
int bufferIndex = getScrollingVelocity() + 1; int bufferIndex = getScrollingVelocity() + 1;
Renderer::pushClipRect(Eigen::Vector2i(0, 0), mSize.cast<int>()); Renderer::pushClipRect(Eigen::Vector2i::Zero(), mSize.cast<int>());
for (int i = extrasCenter + logoBuffersLeft[bufferIndex]; i <= extrasCenter + logoBuffersRight[bufferIndex]; i++) for (int i = extrasCenter + logoBuffersLeft[bufferIndex]; i <= extrasCenter + logoBuffersRight[bufferIndex]; i++)
{ {
@ -485,16 +523,19 @@ void SystemView::renderExtras(const Eigen::Affine3f& trans, float lower, float u
while (index >= (int)mEntries.size()) while (index >= (int)mEntries.size())
index -= mEntries.size(); index -= mEntries.size();
//Only render selected system when not showing
if (mShowing || index == mCursor)
{
Eigen::Affine3f extrasTrans = trans; Eigen::Affine3f extrasTrans = trans;
if (mCarousel.type == HORIZONTAL) if (mCarousel.type == HORIZONTAL)
extrasTrans.translate(Eigen::Vector3f((i - mExtrasCamOffset) * mSize.x(), 0, 0)); extrasTrans.translate(Eigen::Vector3f((i - mExtrasCamOffset) * mSize.x(), 0, 0));
else else
extrasTrans.translate(Eigen::Vector3f(0, (i - mExtrasCamOffset) * mSize.y(), 0)); extrasTrans.translate(Eigen::Vector3f(0, (i - mExtrasCamOffset) * mSize.y(), 0));
Renderer::pushClipRect(Eigen::Vector2i(extrasTrans.translation()[0], extrasTrans.translation()[1]), mSize.cast<int>()); Renderer::pushClipRect(Eigen::Vector2i(extrasTrans.translation()[0], extrasTrans.translation()[1]),
mSize.cast<int>());
SystemViewData data = mEntries.at(index).data; SystemViewData data = mEntries.at(index).data;
for(unsigned int j = 0; j < data.backgroundExtras.size(); j++) for (unsigned int j = 0; j < data.backgroundExtras.size(); j++) {
{
GuiComponent *extra = data.backgroundExtras[j]; GuiComponent *extra = data.backgroundExtras[j];
if (extra->getZIndex() >= lower && extra->getZIndex() < upper) { if (extra->getZIndex() >= lower && extra->getZIndex() < upper) {
extra->render(extrasTrans); extra->render(extrasTrans);
@ -502,6 +543,7 @@ void SystemView::renderExtras(const Eigen::Affine3f& trans, float lower, float u
} }
Renderer::popClipRect(); Renderer::popClipRect();
} }
}
Renderer::popClipRect(); Renderer::popClipRect();
} }
@ -520,12 +562,18 @@ void SystemView::getDefaultElements(void)
{ {
// Carousel // Carousel
mCarousel.type = HORIZONTAL; mCarousel.type = HORIZONTAL;
mCarousel.logoAlignment = ALIGN_CENTER;
mCarousel.size.x() = mSize.x(); mCarousel.size.x() = mSize.x();
mCarousel.size.y() = 0.2325f * mSize.y(); mCarousel.size.y() = 0.2325f * mSize.y();
mCarousel.pos.x() = 0.0f; mCarousel.pos.x() = 0.0f;
mCarousel.pos.y() = 0.5f * (mSize.y() - mCarousel.size.y()); mCarousel.pos.y() = 0.5f * (mSize.y() - mCarousel.size.y());
mCarousel.origin.x() = 0.0f;
mCarousel.origin.y() = 0.0f;
mCarousel.color = 0xFFFFFFD8; mCarousel.color = 0xFFFFFFD8;
mCarousel.logoScale = 1.2f; mCarousel.logoScale = 1.2f;
mCarousel.logoRotation = 7.5;
mCarousel.logoRotationOrigin.x() = -5;
mCarousel.logoRotationOrigin.y() = 0.5;
mCarousel.logoSize.x() = 0.25f * mSize.x(); mCarousel.logoSize.x() = 0.25f * mSize.x();
mCarousel.logoSize.y() = 0.155f * mSize.y(); mCarousel.logoSize.y() = 0.155f * mSize.y();
mCarousel.maxLogoCount = 3; mCarousel.maxLogoCount = 3;
@ -545,11 +593,20 @@ void SystemView::getDefaultElements(void)
void SystemView::getCarouselFromTheme(const ThemeData::ThemeElement* elem) void SystemView::getCarouselFromTheme(const ThemeData::ThemeElement* elem)
{ {
if (elem->has("type")) if (elem->has("type"))
mCarousel.type = !(elem->get<std::string>("type").compare("vertical")) ? VERTICAL : HORIZONTAL; {
if (!(elem->get<std::string>("type").compare("vertical")))
mCarousel.type = VERTICAL;
else if (!(elem->get<std::string>("type").compare("vertical_wheel")))
mCarousel.type = VERTICAL_WHEEL;
else
mCarousel.type = HORIZONTAL;
}
if (elem->has("size")) if (elem->has("size"))
mCarousel.size = elem->get<Eigen::Vector2f>("size").cwiseProduct(mSize); mCarousel.size = elem->get<Eigen::Vector2f>("size").cwiseProduct(mSize);
if (elem->has("pos")) if (elem->has("pos"))
mCarousel.pos = elem->get<Eigen::Vector2f>("pos").cwiseProduct(mSize); mCarousel.pos = elem->get<Eigen::Vector2f>("pos").cwiseProduct(mSize);
if (elem->has("origin"))
mCarousel.origin = elem->get<Eigen::Vector2f>("origin");
if (elem->has("color")) if (elem->has("color"))
mCarousel.color = elem->get<unsigned int>("color"); mCarousel.color = elem->get<unsigned int>("color");
if (elem->has("logoScale")) if (elem->has("logoScale"))
@ -560,4 +617,31 @@ void SystemView::getCarouselFromTheme(const ThemeData::ThemeElement* elem)
mCarousel.maxLogoCount = std::round(elem->get<float>("maxLogoCount")); mCarousel.maxLogoCount = std::round(elem->get<float>("maxLogoCount"));
if (elem->has("zIndex")) if (elem->has("zIndex"))
mCarousel.zIndex = elem->get<float>("zIndex"); mCarousel.zIndex = elem->get<float>("zIndex");
if (elem->has("logoRotation"))
mCarousel.logoRotation = elem->get<float>("logoRotation");
if (elem->has("logoRotationOrigin"))
mCarousel.logoRotationOrigin = elem->get<Eigen::Vector2f>("logoRotationOrigin");
if (elem->has("logoAlignment"))
{
if (!(elem->get<std::string>("logoAlignment").compare("left")))
mCarousel.logoAlignment = ALIGN_LEFT;
else if (!(elem->get<std::string>("logoAlignment").compare("right")))
mCarousel.logoAlignment = ALIGN_RIGHT;
else if (!(elem->get<std::string>("logoAlignment").compare("top")))
mCarousel.logoAlignment = ALIGN_TOP;
else if (!(elem->get<std::string>("logoAlignment").compare("bottom")))
mCarousel.logoAlignment = ALIGN_BOTTOM;
else
mCarousel.logoAlignment = ALIGN_CENTER;
}
}
void SystemView::onShow()
{
mShowing = true;
}
void SystemView::onHide()
{
mShowing = false;
} }

View file

@ -13,13 +13,13 @@ class AnimatedImageComponent;
enum CarouselType : unsigned int enum CarouselType : unsigned int
{ {
HORIZONTAL = 0, HORIZONTAL = 0,
VERTICAL = 1 VERTICAL = 1,
VERTICAL_WHEEL = 2
}; };
struct SystemViewData struct SystemViewData
{ {
std::shared_ptr<GuiComponent> logo; std::shared_ptr<GuiComponent> logo;
std::shared_ptr<GuiComponent> logoSelected;
std::vector<GuiComponent*> backgroundExtras; std::vector<GuiComponent*> backgroundExtras;
}; };
@ -28,8 +28,11 @@ struct SystemViewCarousel
CarouselType type; CarouselType type;
Eigen::Vector2f pos; Eigen::Vector2f pos;
Eigen::Vector2f size; Eigen::Vector2f size;
Eigen::Vector2f origin;
float logoScale; float logoScale;
Eigen::Vector2f logoSpacing; float logoRotation;
Eigen::Vector2f logoRotationOrigin;
Alignment logoAlignment;
unsigned int color; unsigned int color;
int maxLogoCount; // number of logos shown on the carousel int maxLogoCount; // number of logos shown on the carousel
Eigen::Vector2f logoSize; Eigen::Vector2f logoSize;
@ -41,6 +44,9 @@ class SystemView : public IList<SystemViewData, SystemData*>
public: public:
SystemView(Window* window); SystemView(Window* window);
virtual void onShow() override;
virtual void onHide() override;
void goToSystem(SystemData* system, bool animate); void goToSystem(SystemData* system, bool animate);
bool input(InputConfig* config, Input input) override; bool input(InputConfig* config, Input input) override;
@ -76,4 +82,5 @@ private:
float mExtrasFadeOpacity; float mExtrasFadeOpacity;
bool mViewNeedsReload; bool mViewNeedsReload;
bool mShowing;
}; };

View file

@ -72,6 +72,7 @@ void ViewController::goToSystemView(SystemData* system)
systemList->goToSystem(system, false); systemList->goToSystem(system, false);
mCurrentView = systemList; mCurrentView = systemList;
mCurrentView->onShow();
PowerSaver::setState(true); PowerSaver::setState(true);
playViewTransition(); playViewTransition();

View file

@ -13,7 +13,7 @@ ISimpleGameListView::ISimpleGameListView(Window* window, FileData* root) : IGame
mHeaderText.setText("Logo Text"); mHeaderText.setText("Logo Text");
mHeaderText.setSize(mSize.x(), 0); mHeaderText.setSize(mSize.x(), 0);
mHeaderText.setPosition(0, 0); mHeaderText.setPosition(0, 0);
mHeaderText.setAlignment(ALIGN_CENTER); mHeaderText.setHorizontalAlignment(ALIGN_CENTER);
mHeaderText.setDefaultZIndex(50); mHeaderText.setDefaultZIndex(50);
mHeaderImage.setResize(0, mSize.y() * 0.185f); mHeaderImage.setResize(0, mSize.y() * 0.185f);

View file

@ -132,7 +132,6 @@ float GuiComponent::getScale() const
void GuiComponent::setScale(float scale) void GuiComponent::setScale(float scale)
{ {
mScale = scale; mScale = scale;
onSizeChanged();
} }
float GuiComponent::getZIndex() const float GuiComponent::getZIndex() const

View file

@ -127,9 +127,13 @@ std::map< std::string, ElementMapType > ThemeData::sElementMap = boost::assign::
("type", STRING) ("type", STRING)
("size", NORMALIZED_PAIR) ("size", NORMALIZED_PAIR)
("pos", NORMALIZED_PAIR) ("pos", NORMALIZED_PAIR)
("origin", NORMALIZED_PAIR)
("color", COLOR) ("color", COLOR)
("logoScale", FLOAT) ("logoScale", FLOAT)
("logoRotation", FLOAT)
("logoRotationOrigin", NORMALIZED_PAIR)
("logoSize", NORMALIZED_PAIR) ("logoSize", NORMALIZED_PAIR)
("logoAlignment", STRING)
("maxLogoCount", FLOAT) ("maxLogoCount", FLOAT)
("zIndex", FLOAT))); ("zIndex", FLOAT)));

View file

@ -18,7 +18,7 @@ MenuComponent::MenuComponent(Window* window, const char* title, const std::share
// set up title // set up title
mTitle = std::make_shared<TextComponent>(mWindow); mTitle = std::make_shared<TextComponent>(mWindow);
mTitle->setAlignment(ALIGN_CENTER); mTitle->setHorizontalAlignment(ALIGN_CENTER);
mTitle->setColor(0x555555FF); mTitle->setColor(0x555555FF);
setTitle(title, titleFont); setTitle(title, titleFont);
mGrid.setEntry(mTitle, Vector2i(0, 0), false); mGrid.setEntry(mTitle, Vector2i(0, 0), false);

View file

@ -144,7 +144,7 @@ public:
auto font = Font::get(FONT_SIZE_MEDIUM, FONT_PATH_LIGHT); auto font = Font::get(FONT_SIZE_MEDIUM, FONT_PATH_LIGHT);
mText.setFont(font); mText.setFont(font);
mText.setColor(0x777777FF); mText.setColor(0x777777FF);
mText.setAlignment(ALIGN_CENTER); mText.setHorizontalAlignment(ALIGN_CENTER);
addChild(&mText); addChild(&mText);
if(mMultiSelect) if(mMultiSelect)

View file

@ -8,13 +8,17 @@
#include "Settings.h" #include "Settings.h"
TextComponent::TextComponent(Window* window) : GuiComponent(window), TextComponent::TextComponent(Window* window) : GuiComponent(window),
mFont(Font::get(FONT_SIZE_MEDIUM)), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(ALIGN_LEFT), mLineSpacing(1.5f), mBgColor(0), mRenderBackground(false) mFont(Font::get(FONT_SIZE_MEDIUM)), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true),
mHorizontalAlignment(ALIGN_LEFT), mVerticalAlignment(ALIGN_CENTER), mLineSpacing(1.5f), mBgColor(0),
mRenderBackground(false)
{ {
} }
TextComponent::TextComponent(Window* window, const std::string& text, const std::shared_ptr<Font>& font, unsigned int color, Alignment align, TextComponent::TextComponent(Window* window, const std::string& text, const std::shared_ptr<Font>& font, unsigned int color, Alignment align,
Eigen::Vector3f pos, Eigen::Vector2f size, unsigned int bgcolor) : GuiComponent(window), Eigen::Vector3f pos, Eigen::Vector2f size, unsigned int bgcolor) : GuiComponent(window),
mFont(NULL), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true), mAlignment(align), mLineSpacing(1.5f), mBgColor(0), mRenderBackground(false) mFont(NULL), mUppercase(false), mColor(0x000000FF), mAutoCalcExtent(true, true),
mHorizontalAlignment(align), mVerticalAlignment(ALIGN_CENTER), mLineSpacing(1.5f), mBgColor(0),
mRenderBackground(false)
{ {
setFont(font); setFont(font);
setColor(color); setColor(color);
@ -104,7 +108,20 @@ void TextComponent::render(const Eigen::Affine3f& parentTrans)
if(mTextCache) if(mTextCache)
{ {
const Eigen::Vector2f& textSize = mTextCache->metrics.size; const Eigen::Vector2f& textSize = mTextCache->metrics.size;
Eigen::Vector3f off(0, (getSize().y() - textSize.y()) / 2.0f, 0); float yOff;
switch(mVerticalAlignment)
{
case ALIGN_TOP:
yOff = 0;
break;
case ALIGN_BOTTOM:
yOff = (getSize().y() - textSize.y());
break;
case ALIGN_CENTER:
yOff = (getSize().y() - textSize.y()) / 2.0f;
break;
}
Eigen::Vector3f off(0, yOff, 0);
if(Settings::getInstance()->getBool("DebugText")) if(Settings::getInstance()->getBool("DebugText"))
{ {
@ -120,7 +137,7 @@ void TextComponent::render(const Eigen::Affine3f& parentTrans)
// draw the text area, where the text actually is going // draw the text area, where the text actually is going
if(Settings::getInstance()->getBool("DebugText")) if(Settings::getInstance()->getBool("DebugText"))
{ {
switch(mAlignment) switch(mHorizontalAlignment)
{ {
case ALIGN_LEFT: case ALIGN_LEFT:
Renderer::drawRect(0.0f, 0.0f, mTextCache->metrics.size.x(), mTextCache->metrics.size.y(), 0x00000033); Renderer::drawRect(0.0f, 0.0f, mTextCache->metrics.size.x(), mTextCache->metrics.size.y(), 0x00000033);
@ -189,9 +206,9 @@ void TextComponent::onTextChanged()
text.append(abbrev); text.append(abbrev);
mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(text, Eigen::Vector2f(0, 0), (mColor >> 8 << 8) | mOpacity, mSize.x(), mAlignment, mLineSpacing)); mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(text, Eigen::Vector2f(0, 0), (mColor >> 8 << 8) | mOpacity, mSize.x(), mHorizontalAlignment, mLineSpacing));
}else{ }else{
mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(f->wrapText(text, mSize.x()), Eigen::Vector2f(0, 0), (mColor >> 8 << 8) | mOpacity, mSize.x(), mAlignment, mLineSpacing)); mTextCache = std::shared_ptr<TextCache>(f->buildTextCache(f->wrapText(text, mSize.x()), Eigen::Vector2f(0, 0), (mColor >> 8 << 8) | mOpacity, mSize.x(), mHorizontalAlignment, mLineSpacing));
} }
} }
@ -203,12 +220,17 @@ void TextComponent::onColorChanged()
} }
} }
void TextComponent::setAlignment(Alignment align) void TextComponent::setHorizontalAlignment(Alignment align)
{ {
mAlignment = align; mHorizontalAlignment = align;
onTextChanged(); onTextChanged();
} }
void TextComponent::setVerticalAlignment(Alignment align)
{
mVerticalAlignment = align;
}
void TextComponent::setLineSpacing(float spacing) void TextComponent::setLineSpacing(float spacing)
{ {
mLineSpacing = spacing; mLineSpacing = spacing;
@ -248,11 +270,11 @@ void TextComponent::applyTheme(const std::shared_ptr<ThemeData>& theme, const st
{ {
std::string str = elem->get<std::string>("alignment"); std::string str = elem->get<std::string>("alignment");
if(str == "left") if(str == "left")
setAlignment(ALIGN_LEFT); setHorizontalAlignment(ALIGN_LEFT);
else if(str == "center") else if(str == "center")
setAlignment(ALIGN_CENTER); setHorizontalAlignment(ALIGN_CENTER);
else if(str == "right") else if(str == "right")
setAlignment(ALIGN_RIGHT); setHorizontalAlignment(ALIGN_RIGHT);
else else
LOG(LogError) << "Unknown text alignment string: " << str; LOG(LogError) << "Unknown text alignment string: " << str;
} }

View file

@ -23,7 +23,8 @@ public:
void onSizeChanged() override; void onSizeChanged() override;
void setText(const std::string& text); void setText(const std::string& text);
void setColor(unsigned int color); void setColor(unsigned int color);
void setAlignment(Alignment align); void setHorizontalAlignment(Alignment align);
void setVerticalAlignment(Alignment align);
void setLineSpacing(float spacing); void setLineSpacing(float spacing);
void setBackgroundColor(unsigned int color); void setBackgroundColor(unsigned int color);
void setRenderBackground(bool render); void setRenderBackground(bool render);
@ -57,7 +58,8 @@ private:
Eigen::Matrix<bool, 1, 2> mAutoCalcExtent; Eigen::Matrix<bool, 1, 2> mAutoCalcExtent;
std::string mText; std::string mText;
std::shared_ptr<TextCache> mTextCache; std::shared_ptr<TextCache> mTextCache;
Alignment mAlignment; Alignment mHorizontalAlignment;
Alignment mVerticalAlignment;
float mLineSpacing; float mLineSpacing;
}; };

View file

@ -25,7 +25,9 @@ enum Alignment
{ {
ALIGN_LEFT, ALIGN_LEFT,
ALIGN_CENTER, // centers both horizontally and vertically ALIGN_CENTER, // centers both horizontally and vertically
ALIGN_RIGHT ALIGN_RIGHT,
ALIGN_TOP,
ALIGN_BOTTOM
}; };
//A TrueType Font renderer that uses FreeType and OpenGL. //A TrueType Font renderer that uses FreeType and OpenGL.