mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-29 01:25:38 +00:00
carousel enhancements
This commit is contained in:
parent
96fbc1c277
commit
c7b3db244e
21
THEMES.md
21
THEMES.md
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -418,7 +418,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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)));
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue