mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-02-06 15:25:39 +00:00
Added support for theme-controlled transition animations.
This commit is contained in:
parent
1f0bf21675
commit
71b4fc947a
|
@ -294,6 +294,101 @@ void GuiMenu::openUIOptions()
|
||||||
themeAspectRatiosFunc(Settings::getInstance()->getString("ThemeSet"),
|
themeAspectRatiosFunc(Settings::getInstance()->getString("ThemeSet"),
|
||||||
Settings::getInstance()->getString("ThemeAspectRatio"));
|
Settings::getInstance()->getString("ThemeAspectRatio"));
|
||||||
|
|
||||||
|
// Theme transition animations.
|
||||||
|
auto themeTransitionAnimations = std::make_shared<OptionListComponent<std::string>>(
|
||||||
|
getHelpStyle(), "THEME TRANSITION ANIMS", false);
|
||||||
|
std::string selectedAnim {Settings::getInstance()->getString("ThemeTransitionAnimations")};
|
||||||
|
themeTransitionAnimations->add("AUTOMATIC", "automatic", selectedAnim == "automatic");
|
||||||
|
// If there are no objects returned, then there must be a manually modified entry in the
|
||||||
|
// configuration file. Simply set the animation type to "automatic" in this case.
|
||||||
|
if (themeTransitionAnimations->getSelectedObjects().size() == 0)
|
||||||
|
themeTransitionAnimations->selectEntry(0);
|
||||||
|
s->addWithLabel("THEME TRANSITION ANIMATIONS", themeTransitionAnimations);
|
||||||
|
s->addSaveFunc([themeTransitionAnimations, s] {
|
||||||
|
if (themeTransitionAnimations->getSelected() !=
|
||||||
|
Settings::getInstance()->getString("ThemeTransitionAnimations")) {
|
||||||
|
Settings::getInstance()->setString("ThemeTransitionAnimations",
|
||||||
|
themeTransitionAnimations->getSelected());
|
||||||
|
ThemeData::setThemeTransitions();
|
||||||
|
s->setNeedsSaving();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
auto themeTransitionAnimationsFunc = [=](const std::string& selectedTheme,
|
||||||
|
const std::string& selectedTransitionAnimation) {
|
||||||
|
std::map<std::string, ThemeData::ThemeSet, ThemeData::StringComparator>::const_iterator
|
||||||
|
currentSet {themeSets.find(selectedTheme)};
|
||||||
|
if (currentSet == themeSets.cend())
|
||||||
|
return;
|
||||||
|
// We need to recreate the OptionListComponent entries.
|
||||||
|
themeTransitionAnimations->clearEntries();
|
||||||
|
if (currentSet->second.capabilities.legacyTheme) {
|
||||||
|
themeTransitionAnimations->add("Legacy theme set", "automatic", true);
|
||||||
|
themeTransitionAnimations->setEnabled(false);
|
||||||
|
themeTransitionAnimations->setOpacity(DISABLED_OPACITY);
|
||||||
|
themeTransitionAnimations->getParent()
|
||||||
|
->getChild(themeTransitionAnimations->getChildIndex() - 1)
|
||||||
|
->setOpacity(DISABLED_OPACITY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
themeTransitionAnimations->add("AUTOMATIC", "automatic",
|
||||||
|
"automatic" == selectedTransitionAnimation);
|
||||||
|
if (currentSet->second.capabilities.transitions.size() == 1 &&
|
||||||
|
currentSet->second.capabilities.transitions.front().selectable) {
|
||||||
|
std::string label;
|
||||||
|
if (currentSet->second.capabilities.transitions.front().label == "")
|
||||||
|
label = "THEME PROFILE";
|
||||||
|
else
|
||||||
|
label = currentSet->second.capabilities.transitions.front().label;
|
||||||
|
const std::string transitionAnim {
|
||||||
|
currentSet->second.capabilities.transitions.front().name};
|
||||||
|
themeTransitionAnimations->add(label, transitionAnim,
|
||||||
|
transitionAnim == selectedTransitionAnimation);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (size_t i {0}; i < currentSet->second.capabilities.transitions.size(); ++i) {
|
||||||
|
if (!currentSet->second.capabilities.transitions[i].selectable)
|
||||||
|
continue;
|
||||||
|
std::string label;
|
||||||
|
if (currentSet->second.capabilities.transitions[i].label == "")
|
||||||
|
label = "THEME PROFILE " + std::to_string(i + 1);
|
||||||
|
else
|
||||||
|
label = currentSet->second.capabilities.transitions[i].label;
|
||||||
|
const std::string transitionAnim {
|
||||||
|
currentSet->second.capabilities.transitions[i].name};
|
||||||
|
themeTransitionAnimations->add(label, transitionAnim,
|
||||||
|
transitionAnim == selectedTransitionAnimation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (std::find(currentSet->second.capabilities.suppressedTransitionEntries.cbegin(),
|
||||||
|
currentSet->second.capabilities.suppressedTransitionEntries.cend(),
|
||||||
|
"builtin-instant") ==
|
||||||
|
currentSet->second.capabilities.suppressedTransitionEntries.cend()) {
|
||||||
|
themeTransitionAnimations->add("INSTANT (BUILT-IN)", "builtin-instant",
|
||||||
|
"builtin-instant" == selectedTransitionAnimation);
|
||||||
|
}
|
||||||
|
if (std::find(currentSet->second.capabilities.suppressedTransitionEntries.cbegin(),
|
||||||
|
currentSet->second.capabilities.suppressedTransitionEntries.cend(),
|
||||||
|
"builtin-slide") ==
|
||||||
|
currentSet->second.capabilities.suppressedTransitionEntries.cend()) {
|
||||||
|
themeTransitionAnimations->add("SLIDE (BUILT-IN)", "builtin-slide",
|
||||||
|
"builtin-slide" == selectedTransitionAnimation);
|
||||||
|
}
|
||||||
|
if (std::find(currentSet->second.capabilities.suppressedTransitionEntries.cbegin(),
|
||||||
|
currentSet->second.capabilities.suppressedTransitionEntries.cend(),
|
||||||
|
"builtin-fade") ==
|
||||||
|
currentSet->second.capabilities.suppressedTransitionEntries.cend()) {
|
||||||
|
themeTransitionAnimations->add("FADE (BUILT-IN)", "builtin-fade",
|
||||||
|
"builtin-fade" == selectedTransitionAnimation);
|
||||||
|
}
|
||||||
|
if (themeTransitionAnimations->getSelectedObjects().size() == 0)
|
||||||
|
themeTransitionAnimations->selectEntry(0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
themeTransitionAnimationsFunc(Settings::getInstance()->getString("ThemeSet"),
|
||||||
|
Settings::getInstance()->getString("ThemeTransitionAnimations"));
|
||||||
|
|
||||||
// Legacy gamelist view style.
|
// Legacy gamelist view style.
|
||||||
auto gamelistViewStyle = std::make_shared<OptionListComponent<std::string>>(
|
auto gamelistViewStyle = std::make_shared<OptionListComponent<std::string>>(
|
||||||
getHelpStyle(), "LEGACY GAMELIST VIEW STYLE", false);
|
getHelpStyle(), "LEGACY GAMELIST VIEW STYLE", false);
|
||||||
|
@ -318,21 +413,28 @@ void GuiMenu::openUIOptions()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Legacy ransition style.
|
// Legacy transition animations.
|
||||||
auto transitionStyle = std::make_shared<OptionListComponent<std::string>>(
|
auto legacyTransitionAnimations = std::make_shared<OptionListComponent<std::string>>(
|
||||||
getHelpStyle(), "LEGACY TRANSITION STYLE", false);
|
getHelpStyle(), "LEGACY TRANSITION ANIMS", false);
|
||||||
std::vector<std::string> transitions;
|
const std::string& selectedLegacyAnimations {
|
||||||
transitions.push_back("slide");
|
Settings::getInstance()->getString("LegacyTransitionAnimations")};
|
||||||
transitions.push_back("fade");
|
legacyTransitionAnimations->add("INSTANT", "builtin-instant",
|
||||||
transitions.push_back("instant");
|
selectedLegacyAnimations == "builtin-instant");
|
||||||
for (auto it = transitions.cbegin(); it != transitions.cend(); ++it)
|
legacyTransitionAnimations->add("SLIDE", "builtin-slide",
|
||||||
transitionStyle->add(*it, *it,
|
selectedLegacyAnimations == "builtin-slide");
|
||||||
Settings::getInstance()->getString("TransitionStyle") == *it);
|
legacyTransitionAnimations->add("FADE", "builtin-fade",
|
||||||
s->addWithLabel("LEGACY TRANSITION STYLE", transitionStyle);
|
selectedLegacyAnimations == "builtin-fade");
|
||||||
s->addSaveFunc([transitionStyle, s] {
|
// If there are no objects returned, then there must be a manually modified entry in the
|
||||||
if (transitionStyle->getSelected() !=
|
// configuration file. Simply set the animations to "builtin-instant" in this case.
|
||||||
Settings::getInstance()->getString("TransitionStyle")) {
|
if (legacyTransitionAnimations->getSelectedObjects().size() == 0)
|
||||||
Settings::getInstance()->setString("TransitionStyle", transitionStyle->getSelected());
|
legacyTransitionAnimations->selectEntry(0);
|
||||||
|
s->addWithLabel("LEGACY TRANSITION ANIMATIONS", legacyTransitionAnimations);
|
||||||
|
s->addSaveFunc([legacyTransitionAnimations, s] {
|
||||||
|
if (legacyTransitionAnimations->getSelected() !=
|
||||||
|
Settings::getInstance()->getString("LegacyTransitionAnimations")) {
|
||||||
|
Settings::getInstance()->setString("LegacyTransitionAnimations",
|
||||||
|
legacyTransitionAnimations->getSelected());
|
||||||
|
ThemeData::setThemeTransitions();
|
||||||
s->setNeedsSaving();
|
s->setNeedsSaving();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -729,6 +831,7 @@ void GuiMenu::openUIOptions()
|
||||||
themeVariantsFunc(themeName, themeVariant->getSelected());
|
themeVariantsFunc(themeName, themeVariant->getSelected());
|
||||||
themeColorSchemesFunc(themeName, themeColorScheme->getSelected());
|
themeColorSchemesFunc(themeName, themeColorScheme->getSelected());
|
||||||
themeAspectRatiosFunc(themeName, themeAspectRatio->getSelected());
|
themeAspectRatiosFunc(themeName, themeAspectRatio->getSelected());
|
||||||
|
themeTransitionAnimationsFunc(themeName, themeTransitionAnimations->getSelected());
|
||||||
}
|
}
|
||||||
int selectableVariants {0};
|
int selectableVariants {0};
|
||||||
for (auto& variant : selectedSet->second.capabilities.variants) {
|
for (auto& variant : selectedSet->second.capabilities.variants) {
|
||||||
|
@ -785,12 +888,18 @@ void GuiMenu::openUIOptions()
|
||||||
gamelistViewStyle->getParent()
|
gamelistViewStyle->getParent()
|
||||||
->getChild(gamelistViewStyle->getChildIndex() - 1)
|
->getChild(gamelistViewStyle->getChildIndex() - 1)
|
||||||
->setOpacity(DISABLED_OPACITY);
|
->setOpacity(DISABLED_OPACITY);
|
||||||
// TEMPORARY
|
|
||||||
// transitionStyle->setEnabled(false);
|
themeTransitionAnimations->setEnabled(true);
|
||||||
// transitionStyle->setOpacity(DISABLED_OPACITY);
|
themeTransitionAnimations->setOpacity(1.0f);
|
||||||
// transitionStyle->getParent()
|
themeTransitionAnimations->getParent()
|
||||||
// ->getChild(transitionStyle->getChildIndex() - 1)
|
->getChild(themeTransitionAnimations->getChildIndex() - 1)
|
||||||
// ->setOpacity(DISABLED_OPACITY);
|
->setOpacity(1.0f);
|
||||||
|
|
||||||
|
legacyTransitionAnimations->setEnabled(false);
|
||||||
|
legacyTransitionAnimations->setOpacity(DISABLED_OPACITY);
|
||||||
|
legacyTransitionAnimations->getParent()
|
||||||
|
->getChild(legacyTransitionAnimations->getChildIndex() - 1)
|
||||||
|
->setOpacity(DISABLED_OPACITY);
|
||||||
|
|
||||||
// Pillarboxes are theme-controlled for newer themes.
|
// Pillarboxes are theme-controlled for newer themes.
|
||||||
gamelistVideoPillarbox->setEnabled(false);
|
gamelistVideoPillarbox->setEnabled(false);
|
||||||
|
@ -813,10 +922,16 @@ void GuiMenu::openUIOptions()
|
||||||
->getChild(gamelistViewStyle->getChildIndex() - 1)
|
->getChild(gamelistViewStyle->getChildIndex() - 1)
|
||||||
->setOpacity(1.0f);
|
->setOpacity(1.0f);
|
||||||
|
|
||||||
transitionStyle->setEnabled(true);
|
themeTransitionAnimations->setEnabled(false);
|
||||||
transitionStyle->setOpacity(1.0f);
|
themeTransitionAnimations->setOpacity(DISABLED_OPACITY);
|
||||||
transitionStyle->getParent()
|
themeTransitionAnimations->getParent()
|
||||||
->getChild(transitionStyle->getChildIndex() - 1)
|
->getChild(themeTransitionAnimations->getChildIndex() - 1)
|
||||||
|
->setOpacity(DISABLED_OPACITY);
|
||||||
|
|
||||||
|
legacyTransitionAnimations->setEnabled(true);
|
||||||
|
legacyTransitionAnimations->setOpacity(1.0f);
|
||||||
|
legacyTransitionAnimations->getParent()
|
||||||
|
->getChild(legacyTransitionAnimations->getChildIndex() - 1)
|
||||||
->setOpacity(1.0f);
|
->setOpacity(1.0f);
|
||||||
|
|
||||||
gamelistVideoPillarbox->setEnabled(true);
|
gamelistVideoPillarbox->setEnabled(true);
|
||||||
|
|
|
@ -227,8 +227,9 @@ void SystemView::onCursorChanged(const CursorState& state)
|
||||||
{
|
{
|
||||||
const int cursor {mPrimary->getCursor()};
|
const int cursor {mPrimary->getCursor()};
|
||||||
const int scrollVelocity {mPrimary->getScrollingVelocity()};
|
const int scrollVelocity {mPrimary->getScrollingVelocity()};
|
||||||
const std::string& transitionStyle {Settings::getInstance()->getString("TransitionStyle")};
|
const ViewTransitionAnimation transitionAnim {static_cast<ViewTransitionAnimation>(
|
||||||
mFadeTransitions = transitionStyle == "fade";
|
Settings::getInstance()->getInt("TransitionsSystemToSystem"))};
|
||||||
|
mFadeTransitions = (transitionAnim == ViewTransitionAnimation::FADE);
|
||||||
|
|
||||||
// Some logic needed to avoid various navigation glitches with GridComponent and
|
// Some logic needed to avoid various navigation glitches with GridComponent and
|
||||||
// TextListComponent.
|
// TextListComponent.
|
||||||
|
@ -278,7 +279,7 @@ void SystemView::onCursorChanged(const CursorState& state)
|
||||||
|
|
||||||
// This is needed to avoid erratic camera movements during extreme navigation input when using
|
// This is needed to avoid erratic camera movements during extreme navigation input when using
|
||||||
// slide transitions. This should very rarely occur during normal application usage.
|
// slide transitions. This should very rarely occur during normal application usage.
|
||||||
if (transitionStyle == "slide") {
|
if (transitionAnim == ViewTransitionAnimation::SLIDE) {
|
||||||
bool resetCamOffset {false};
|
bool resetCamOffset {false};
|
||||||
|
|
||||||
if (scrollVelocity == -1 && mPreviousScrollVelocity == 1) {
|
if (scrollVelocity == -1 && mPreviousScrollVelocity == 1) {
|
||||||
|
@ -372,7 +373,7 @@ void SystemView::onCursorChanged(const CursorState& state)
|
||||||
animTime =
|
animTime =
|
||||||
glm::clamp(std::fabs(glm::mix(0.0f, animTime, timeDiff * 1.5f)), timeMin, animTime);
|
glm::clamp(std::fabs(glm::mix(0.0f, animTime, timeDiff * 1.5f)), timeMin, animTime);
|
||||||
|
|
||||||
if (transitionStyle == "fade") {
|
if (transitionAnim == ViewTransitionAnimation::FADE) {
|
||||||
float startFade {mFadeOpacity};
|
float startFade {mFadeOpacity};
|
||||||
anim = new LambdaAnimation(
|
anim = new LambdaAnimation(
|
||||||
[this, startFade, endPos](float t) {
|
[this, startFade, endPos](float t) {
|
||||||
|
@ -398,7 +399,7 @@ void SystemView::onCursorChanged(const CursorState& state)
|
||||||
},
|
},
|
||||||
static_cast<int>(animTime * 1.3f));
|
static_cast<int>(animTime * 1.3f));
|
||||||
}
|
}
|
||||||
else if (transitionStyle == "slide") {
|
else if (transitionAnim == ViewTransitionAnimation::SLIDE) {
|
||||||
mUpdatedGameCount = false;
|
mUpdatedGameCount = false;
|
||||||
anim = new LambdaAnimation(
|
anim = new LambdaAnimation(
|
||||||
[this, startPos, endPos, posMax](float t) {
|
[this, startPos, endPos, posMax](float t) {
|
||||||
|
@ -815,7 +816,8 @@ void SystemView::populate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mFadeTransitions = Settings::getInstance()->getString("TransitionStyle") == "fade";
|
mFadeTransitions = (static_cast<ViewTransitionAnimation>(Settings::getInstance()->getInt(
|
||||||
|
"TransitionsSystemToSystem")) == ViewTransitionAnimation::FADE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemView::updateGameCount()
|
void SystemView::updateGameCount()
|
||||||
|
|
|
@ -37,6 +37,7 @@ ViewController::ViewController() noexcept
|
||||||
, mCurrentView {nullptr}
|
, mCurrentView {nullptr}
|
||||||
, mPreviousView {nullptr}
|
, mPreviousView {nullptr}
|
||||||
, mSkipView {nullptr}
|
, mSkipView {nullptr}
|
||||||
|
, mLastTransitionAnim {ViewTransitionAnimation::INSTANT}
|
||||||
, mGameToLaunch {nullptr}
|
, mGameToLaunch {nullptr}
|
||||||
, mCamera {Renderer::getIdentity()}
|
, mCamera {Renderer::getIdentity()}
|
||||||
, mSystemViewTransition {false}
|
, mSystemViewTransition {false}
|
||||||
|
@ -220,7 +221,7 @@ void ViewController::goToStart(bool playTransition)
|
||||||
|
|
||||||
// If a specific system is requested, go directly to its game list.
|
// If a specific system is requested, go directly to its game list.
|
||||||
auto requestedSystem = Settings::getInstance()->getString("StartupSystem");
|
auto requestedSystem = Settings::getInstance()->getString("StartupSystem");
|
||||||
if ("" != requestedSystem && "retropie" != requestedSystem) {
|
if (requestedSystem != "") {
|
||||||
for (auto it = SystemData::sSystemVector.cbegin(); // Line break.
|
for (auto it = SystemData::sSystemVector.cbegin(); // Line break.
|
||||||
it != SystemData::sSystemVector.cend(); ++it) {
|
it != SystemData::sSystemVector.cend(); ++it) {
|
||||||
if ((*it)->getName() == requestedSystem) {
|
if ((*it)->getName() == requestedSystem) {
|
||||||
|
@ -263,7 +264,7 @@ bool ViewController::isCameraMoving()
|
||||||
|
|
||||||
void ViewController::cancelViewTransitions()
|
void ViewController::cancelViewTransitions()
|
||||||
{
|
{
|
||||||
if (Settings::getInstance()->getString("TransitionStyle") == "slide") {
|
if (mLastTransitionAnim == ViewTransitionAnimation::SLIDE) {
|
||||||
if (isCameraMoving()) {
|
if (isCameraMoving()) {
|
||||||
mCamera[3].x = -mCurrentView->getPosition().x;
|
mCamera[3].x = -mCurrentView->getPosition().x;
|
||||||
mCamera[3].y = -mCurrentView->getPosition().y;
|
mCamera[3].y = -mCurrentView->getPosition().y;
|
||||||
|
@ -277,7 +278,7 @@ void ViewController::cancelViewTransitions()
|
||||||
mSkipView = nullptr;
|
mSkipView = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Settings::getInstance()->getString("TransitionStyle") == "fade") {
|
else if (mLastTransitionAnim == ViewTransitionAnimation::FADE) {
|
||||||
if (isAnimationPlaying(0)) {
|
if (isAnimationPlaying(0)) {
|
||||||
finishAnimation(0);
|
finishAnimation(0);
|
||||||
mCancelledTransition = true;
|
mCancelledTransition = true;
|
||||||
|
@ -354,8 +355,11 @@ void ViewController::goToSystemView(SystemData* system, bool playTransition)
|
||||||
|
|
||||||
// Application startup animation.
|
// Application startup animation.
|
||||||
if (applicationStartup) {
|
if (applicationStartup) {
|
||||||
|
const ViewTransitionAnimation transitionAnim {static_cast<ViewTransitionAnimation>(
|
||||||
|
Settings::getInstance()->getInt("TransitionsStartupToSystem"))};
|
||||||
|
|
||||||
mCamera = glm::translate(mCamera, glm::round(-mCurrentView->getPosition()));
|
mCamera = glm::translate(mCamera, glm::round(-mCurrentView->getPosition()));
|
||||||
if (Settings::getInstance()->getString("TransitionStyle") == "slide") {
|
if (transitionAnim == ViewTransitionAnimation::SLIDE) {
|
||||||
if (getSystemListView()->getPrimaryType() == SystemView::PrimaryType::CAROUSEL) {
|
if (getSystemListView()->getPrimaryType() == SystemView::PrimaryType::CAROUSEL) {
|
||||||
if (getSystemListView()->getCarouselType() ==
|
if (getSystemListView()->getCarouselType() ==
|
||||||
CarouselComponent<SystemData*>::CarouselType::HORIZONTAL ||
|
CarouselComponent<SystemData*>::CarouselType::HORIZONTAL ||
|
||||||
|
@ -370,7 +374,7 @@ void ViewController::goToSystemView(SystemData* system, bool playTransition)
|
||||||
}
|
}
|
||||||
updateHelpPrompts();
|
updateHelpPrompts();
|
||||||
}
|
}
|
||||||
else if (Settings::getInstance()->getString("TransitionStyle") == "fade") {
|
else if (transitionAnim == ViewTransitionAnimation::FADE) {
|
||||||
if (getSystemListView()->getPrimaryType() == SystemView::PrimaryType::CAROUSEL) {
|
if (getSystemListView()->getPrimaryType() == SystemView::PrimaryType::CAROUSEL) {
|
||||||
if (getSystemListView()->getCarouselType() ==
|
if (getSystemListView()->getCarouselType() ==
|
||||||
CarouselComponent<SystemData*>::CarouselType::HORIZONTAL ||
|
CarouselComponent<SystemData*>::CarouselType::HORIZONTAL ||
|
||||||
|
@ -389,18 +393,21 @@ void ViewController::goToSystemView(SystemData* system, bool playTransition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (applicationStartup) {
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
// The startup animations are very choppy on macOS as of moving to SDL 2.0.18 so the
|
// The startup animations are very choppy on macOS as of moving to SDL 2.0.18 so the
|
||||||
// best user experience is to simply disable them on this OS.
|
// best user experience is to simply disable them on this OS.
|
||||||
if (applicationStartup)
|
playViewTransition(ViewTransition::STARTUP_TO_SYSTEM, true);
|
||||||
playViewTransition(true);
|
|
||||||
else if (playTransition)
|
|
||||||
#else
|
#else
|
||||||
if (playTransition || applicationStartup)
|
playViewTransition(ViewTransition::STARTUP_TO_SYSTEM);
|
||||||
#endif
|
#endif
|
||||||
playViewTransition();
|
}
|
||||||
else
|
else if (playTransition) {
|
||||||
playViewTransition(true);
|
playViewTransition(ViewTransition::GAMELIST_TO_SYSTEM);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
playViewTransition(ViewTransition::GAMELIST_TO_SYSTEM, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewController::goToSystem(SystemData* system, bool animate)
|
void ViewController::goToSystem(SystemData* system, bool animate)
|
||||||
|
@ -433,21 +440,37 @@ void ViewController::goToGamelist(SystemData* system)
|
||||||
bool wrapFirstToLast {false};
|
bool wrapFirstToLast {false};
|
||||||
bool wrapLastToFirst {false};
|
bool wrapLastToFirst {false};
|
||||||
bool slideTransitions {false};
|
bool slideTransitions {false};
|
||||||
|
bool fadeTransitions {false};
|
||||||
|
|
||||||
if (mCurrentView != nullptr)
|
if (mCurrentView != nullptr)
|
||||||
mCurrentView->onTransition();
|
mCurrentView->onTransition();
|
||||||
|
|
||||||
if (Settings::getInstance()->getString("TransitionStyle") == "slide")
|
ViewTransition transitionType;
|
||||||
|
ViewTransitionAnimation transitionAnim;
|
||||||
|
|
||||||
|
if (mState.viewing == SYSTEM_SELECT) {
|
||||||
|
transitionType = ViewTransition::SYSTEM_TO_GAMELIST;
|
||||||
|
transitionAnim = static_cast<ViewTransitionAnimation>(
|
||||||
|
Settings::getInstance()->getInt("TransitionsSystemToGamelist"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
transitionType = ViewTransition::GAMELIST_TO_GAMELIST;
|
||||||
|
transitionAnim = static_cast<ViewTransitionAnimation>(
|
||||||
|
Settings::getInstance()->getInt("TransitionsGamelistToGamelist"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transitionAnim == ViewTransitionAnimation::SLIDE)
|
||||||
slideTransitions = true;
|
slideTransitions = true;
|
||||||
|
|
||||||
|
if (transitionAnim == ViewTransitionAnimation::FADE)
|
||||||
|
fadeTransitions = true;
|
||||||
|
|
||||||
// Restore the X position for the view, if it was previously moved.
|
// Restore the X position for the view, if it was previously moved.
|
||||||
if (mWrappedViews)
|
if (mWrappedViews)
|
||||||
restoreViewPosition();
|
restoreViewPosition();
|
||||||
|
|
||||||
if (mPreviousView && Settings::getInstance()->getString("TransitionStyle") == "fade" &&
|
if (mPreviousView && fadeTransitions && isAnimationPlaying(0))
|
||||||
isAnimationPlaying(0)) {
|
|
||||||
mPreviousView->onHide();
|
mPreviousView->onHide();
|
||||||
}
|
|
||||||
|
|
||||||
if (mPreviousView) {
|
if (mPreviousView) {
|
||||||
mSkipView = mPreviousView;
|
mSkipView = mPreviousView;
|
||||||
|
@ -540,12 +563,17 @@ void ViewController::goToGamelist(SystemData* system)
|
||||||
|
|
||||||
// Application startup animation, if starting in a gamelist rather than in the system view.
|
// Application startup animation, if starting in a gamelist rather than in the system view.
|
||||||
if (mState.viewing == NOTHING) {
|
if (mState.viewing == NOTHING) {
|
||||||
|
if (mLastTransitionAnim == ViewTransitionAnimation::FADE)
|
||||||
|
cancelViewTransitions();
|
||||||
|
transitionType = ViewTransition::STARTUP_TO_GAMELIST;
|
||||||
mCamera = glm::translate(mCamera, glm::round(-mCurrentView->getPosition()));
|
mCamera = glm::translate(mCamera, glm::round(-mCurrentView->getPosition()));
|
||||||
if (Settings::getInstance()->getString("TransitionStyle") == "slide") {
|
if (static_cast<ViewTransitionAnimation>(Settings::getInstance()->getInt(
|
||||||
|
"TransitionsStartupToGamelist")) == ViewTransitionAnimation::SLIDE) {
|
||||||
mCamera[3].y -= Renderer::getScreenHeight();
|
mCamera[3].y -= Renderer::getScreenHeight();
|
||||||
updateHelpPrompts();
|
updateHelpPrompts();
|
||||||
}
|
}
|
||||||
else if (Settings::getInstance()->getString("TransitionStyle") == "fade") {
|
else if (static_cast<ViewTransitionAnimation>(Settings::getInstance()->getInt(
|
||||||
|
"TransitionsStartupToGamelist")) == ViewTransitionAnimation::FADE) {
|
||||||
mCamera[3].y += Renderer::getScreenHeight() * 2.0f;
|
mCamera[3].y += Renderer::getScreenHeight() * 2.0f;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -570,14 +598,14 @@ void ViewController::goToGamelist(SystemData* system)
|
||||||
if (mCurrentView)
|
if (mCurrentView)
|
||||||
mCurrentView->onShow();
|
mCurrentView->onShow();
|
||||||
|
|
||||||
playViewTransition();
|
playViewTransition(transitionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewController::playViewTransition(bool instant)
|
void ViewController::playViewTransition(ViewTransition transitionType, bool instant)
|
||||||
{
|
{
|
||||||
mCancelledTransition = false;
|
mCancelledTransition = false;
|
||||||
|
|
||||||
glm::vec3 target {};
|
glm::vec3 target {0.0f, 0.0f, 0.0f};
|
||||||
if (mCurrentView)
|
if (mCurrentView)
|
||||||
target = mCurrentView->getPosition();
|
target = mCurrentView->getPosition();
|
||||||
|
|
||||||
|
@ -586,9 +614,30 @@ void ViewController::playViewTransition(bool instant)
|
||||||
if (target == static_cast<glm::vec3>(-mCamera[3]) && !isAnimationPlaying(0))
|
if (target == static_cast<glm::vec3>(-mCamera[3]) && !isAnimationPlaying(0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string transition_style {Settings::getInstance()->getString("TransitionStyle")};
|
ViewTransitionAnimation transitionAnim {ViewTransitionAnimation::INSTANT};
|
||||||
|
|
||||||
if (instant || transition_style == "instant") {
|
if (transitionType == ViewTransition::SYSTEM_TO_SYSTEM)
|
||||||
|
transitionAnim = static_cast<ViewTransitionAnimation>(
|
||||||
|
Settings::getInstance()->getInt("TransitionsSystemToSystem"));
|
||||||
|
else if (transitionType == ViewTransition::SYSTEM_TO_GAMELIST)
|
||||||
|
transitionAnim = static_cast<ViewTransitionAnimation>(
|
||||||
|
Settings::getInstance()->getInt("TransitionsSystemToGamelist"));
|
||||||
|
else if (transitionType == ViewTransition::GAMELIST_TO_GAMELIST)
|
||||||
|
transitionAnim = static_cast<ViewTransitionAnimation>(
|
||||||
|
Settings::getInstance()->getInt("TransitionsGamelistToGamelist"));
|
||||||
|
else if (transitionType == ViewTransition::GAMELIST_TO_SYSTEM)
|
||||||
|
transitionAnim = static_cast<ViewTransitionAnimation>(
|
||||||
|
Settings::getInstance()->getInt("TransitionsGamelistToSystem"));
|
||||||
|
else if (transitionType == ViewTransition::STARTUP_TO_SYSTEM)
|
||||||
|
transitionAnim = static_cast<ViewTransitionAnimation>(
|
||||||
|
Settings::getInstance()->getInt("TransitionsStartupToSystem"));
|
||||||
|
else
|
||||||
|
transitionAnim = static_cast<ViewTransitionAnimation>(
|
||||||
|
Settings::getInstance()->getInt("TransitionsStartupToGamelist"));
|
||||||
|
|
||||||
|
mLastTransitionAnim = transitionAnim;
|
||||||
|
|
||||||
|
if (instant || transitionAnim == ViewTransitionAnimation::INSTANT) {
|
||||||
setAnimation(new LambdaAnimation(
|
setAnimation(new LambdaAnimation(
|
||||||
[this, target](float /*t*/) {
|
[this, target](float /*t*/) {
|
||||||
this->mCamera[3].x = -target.x;
|
this->mCamera[3].x = -target.x;
|
||||||
|
@ -600,7 +649,7 @@ void ViewController::playViewTransition(bool instant)
|
||||||
1));
|
1));
|
||||||
updateHelpPrompts();
|
updateHelpPrompts();
|
||||||
}
|
}
|
||||||
else if (transition_style == "fade") {
|
else if (transitionAnim == ViewTransitionAnimation::FADE) {
|
||||||
// Stop whatever's currently playing, leaving mFadeOpacity wherever it is.
|
// Stop whatever's currently playing, leaving mFadeOpacity wherever it is.
|
||||||
cancelAnimation(0);
|
cancelAnimation(0);
|
||||||
|
|
||||||
|
@ -641,7 +690,7 @@ void ViewController::playViewTransition(bool instant)
|
||||||
advanceAnimation(0, static_cast<int>(mFadeOpacity * FADE_DURATION));
|
advanceAnimation(0, static_cast<int>(mFadeOpacity * FADE_DURATION));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (transition_style == "slide") {
|
else if (transitionAnim == ViewTransitionAnimation::SLIDE) {
|
||||||
auto slideCallback = [this]() {
|
auto slideCallback = [this]() {
|
||||||
if (mSkipView) {
|
if (mSkipView) {
|
||||||
mSkipView->onHide();
|
mSkipView->onHide();
|
||||||
|
@ -1046,7 +1095,7 @@ void ViewController::render(const glm::mat4& parentTrans)
|
||||||
|
|
||||||
void ViewController::preload()
|
void ViewController::preload()
|
||||||
{
|
{
|
||||||
unsigned int systemCount = static_cast<int>(SystemData::sSystemVector.size());
|
unsigned int systemCount {static_cast<unsigned int>(SystemData::sSystemVector.size())};
|
||||||
|
|
||||||
// This reduces the amount of texture pop-in when loading theme extras.
|
// This reduces the amount of texture pop-in when loading theme extras.
|
||||||
if (!SystemData::sSystemVector.empty())
|
if (!SystemData::sSystemVector.empty())
|
||||||
|
@ -1064,6 +1113,8 @@ void ViewController::preload()
|
||||||
getGamelistView(*it)->preloadGamelist();
|
getGamelistView(*it)->preloadGamelist();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThemeData::setThemeTransitions();
|
||||||
|
|
||||||
// Load navigation sounds, either from the theme if it supports it, or otherwise from
|
// Load navigation sounds, either from the theme if it supports it, or otherwise from
|
||||||
// the bundled fallback sound files.
|
// the bundled fallback sound files.
|
||||||
bool themeSoundSupport {false};
|
bool themeSoundSupport {false};
|
||||||
|
@ -1082,7 +1133,7 @@ void ViewController::reloadGamelistView(GamelistView* view, bool reloadTheme)
|
||||||
{
|
{
|
||||||
for (auto it = mGamelistViews.cbegin(); it != mGamelistViews.cend(); ++it) {
|
for (auto it = mGamelistViews.cbegin(); it != mGamelistViews.cend(); ++it) {
|
||||||
if (it->second.get() == view) {
|
if (it->second.get() == view) {
|
||||||
bool isCurrent {(mCurrentView == it->second)};
|
bool isCurrent {mCurrentView == it->second};
|
||||||
SystemData* system {it->first};
|
SystemData* system {it->first};
|
||||||
FileData* cursor {view->getCursor()};
|
FileData* cursor {view->getCursor()};
|
||||||
|
|
||||||
|
@ -1147,6 +1198,8 @@ void ViewController::reloadAll()
|
||||||
it->first->getIndex()->resetFilters();
|
it->first->getIndex()->resetFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThemeData::setThemeTransitions();
|
||||||
|
|
||||||
// Rebuild SystemListView.
|
// Rebuild SystemListView.
|
||||||
mSystemListView.reset();
|
mSystemListView.reset();
|
||||||
getSystemListView();
|
getSystemListView();
|
||||||
|
@ -1160,7 +1213,7 @@ void ViewController::reloadAll()
|
||||||
mCurrentView = getGamelistView(mState.getSystem());
|
mCurrentView = getGamelistView(mState.getSystem());
|
||||||
}
|
}
|
||||||
else if (mState.viewing == SYSTEM_SELECT) {
|
else if (mState.viewing == SYSTEM_SELECT) {
|
||||||
SystemData* system = mState.getSystem();
|
SystemData* system {mState.getSystem()};
|
||||||
mSystemListView->goToSystem(system, false);
|
mSystemListView->goToSystem(system, false);
|
||||||
mCurrentView = mSystemListView;
|
mCurrentView = mSystemListView;
|
||||||
mCamera[3].x = 0.0f;
|
mCamera[3].x = 0.0f;
|
||||||
|
|
|
@ -160,7 +160,7 @@ private:
|
||||||
std::string mRomDirectory;
|
std::string mRomDirectory;
|
||||||
GuiMsgBox* mNoGamesMessageBox;
|
GuiMsgBox* mNoGamesMessageBox;
|
||||||
|
|
||||||
void playViewTransition(bool instant = false);
|
void playViewTransition(ViewTransition transitionType, bool instant = false);
|
||||||
int getSystemId(SystemData* system);
|
int getSystemId(SystemData* system);
|
||||||
// Restore view position if it was moved during wrap around.
|
// Restore view position if it was moved during wrap around.
|
||||||
void restoreViewPosition();
|
void restoreViewPosition();
|
||||||
|
@ -170,6 +170,7 @@ private:
|
||||||
std::shared_ptr<GuiComponent> mSkipView;
|
std::shared_ptr<GuiComponent> mSkipView;
|
||||||
std::map<SystemData*, std::shared_ptr<GamelistView>> mGamelistViews;
|
std::map<SystemData*, std::shared_ptr<GamelistView>> mGamelistViews;
|
||||||
std::shared_ptr<SystemView> mSystemListView;
|
std::shared_ptr<SystemView> mSystemListView;
|
||||||
|
ViewTransitionAnimation mLastTransitionAnim;
|
||||||
|
|
||||||
std::vector<std::string> mGameEndEventParams;
|
std::vector<std::string> mGameEndEventParams;
|
||||||
FileData* mGameToLaunch;
|
FileData* mGameToLaunch;
|
||||||
|
|
|
@ -34,6 +34,21 @@ class InputConfig;
|
||||||
class ThemeData;
|
class ThemeData;
|
||||||
class Window;
|
class Window;
|
||||||
|
|
||||||
|
enum class ViewTransition {
|
||||||
|
SYSTEM_TO_SYSTEM,
|
||||||
|
SYSTEM_TO_GAMELIST,
|
||||||
|
GAMELIST_TO_GAMELIST,
|
||||||
|
GAMELIST_TO_SYSTEM,
|
||||||
|
STARTUP_TO_SYSTEM,
|
||||||
|
STARTUP_TO_GAMELIST
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ViewTransitionAnimation {
|
||||||
|
INSTANT,
|
||||||
|
SLIDE,
|
||||||
|
FADE
|
||||||
|
};
|
||||||
|
|
||||||
enum Alignment {
|
enum Alignment {
|
||||||
ALIGN_LEFT,
|
ALIGN_LEFT,
|
||||||
ALIGN_CENTER, // Used for both horizontal and vertical alignments.
|
ALIGN_CENTER, // Used for both horizontal and vertical alignments.
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
|
#include "GuiComponent.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Scripting.h"
|
#include "Scripting.h"
|
||||||
#include "utils/FileSystemUtil.h"
|
#include "utils/FileSystemUtil.h"
|
||||||
|
@ -20,10 +21,8 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// These values are NOT saved to es_settings.xml since they're not set via
|
// These settings are not saved to es_settings.xml. Most can be set using command-line
|
||||||
// the in-program settings menu. Most can be set using command-line arguments,
|
// arguments but a couple are debug flags or used for other application-internal purposes.
|
||||||
// but some are debug flags that are either hardcoded or set by internal debug
|
|
||||||
// functions.
|
|
||||||
std::vector<std::string> settingsSkipSaving {
|
std::vector<std::string> settingsSkipSaving {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// These options can be set using command-line arguments:
|
// These options can be set using command-line arguments:
|
||||||
|
@ -38,18 +37,24 @@ namespace
|
||||||
"ForceKiosk", // --force-kiosk
|
"ForceKiosk", // --force-kiosk
|
||||||
"ForceKid", // --force-kid
|
"ForceKid", // --force-kid
|
||||||
|
|
||||||
// These options are not shown in the --help text and are intended
|
// These command-line argument options are not shown in the --help text and are intended
|
||||||
// for debugging and testing purposes:
|
// for debugging and testing purposes:
|
||||||
"ScreenWidth", // Set via --screensize [width] [height]
|
"ScreenWidth", // Set via --screensize [width] [height]
|
||||||
"ScreenHeight", // set via --screensize [width] [height]
|
"ScreenHeight", // set via --screensize [width] [height]
|
||||||
"ScreenOffsetX", // Set via --screenoffset [X] [Y]
|
"ScreenOffsetX", // Set via --screenoffset [X] [Y]
|
||||||
"ScreenOffsetY", // Set via --screenoffset [X] [Y]
|
"ScreenOffsetY", // Set via --screenoffset [X] [Y]
|
||||||
|
|
||||||
// These options are not configurable from the command-line:
|
// These options are only used internally during the application session:
|
||||||
"DebugGrid",
|
"DebugGrid",
|
||||||
"DebugText",
|
"DebugText",
|
||||||
"DebugImage",
|
"DebugImage",
|
||||||
"ScraperFilter"
|
"ScraperFilter",
|
||||||
|
"TransitionsSystemToSystem",
|
||||||
|
"TransitionsSystemToGamelist",
|
||||||
|
"TransitionsGamelistToGamelist",
|
||||||
|
"TransitionsGamelistToSystem",
|
||||||
|
"TransitionsStartupToSystem",
|
||||||
|
"TransitionsStartupToGamelist"
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -151,8 +156,9 @@ void Settings::setDefaults()
|
||||||
mStringMap["ThemeVariant"] = {"", ""};
|
mStringMap["ThemeVariant"] = {"", ""};
|
||||||
mStringMap["ThemeColorScheme"] = {"", ""};
|
mStringMap["ThemeColorScheme"] = {"", ""};
|
||||||
mStringMap["ThemeAspectRatio"] = {"", ""};
|
mStringMap["ThemeAspectRatio"] = {"", ""};
|
||||||
|
mStringMap["ThemeTransitionAnimations"] = {"automatic", "automatic"};
|
||||||
mStringMap["GamelistViewStyle"] = {"automatic", "automatic"};
|
mStringMap["GamelistViewStyle"] = {"automatic", "automatic"};
|
||||||
mStringMap["TransitionStyle"] = {"slide", "slide"};
|
mStringMap["LegacyTransitionAnimations"] = {"builtin-instant", "builtin-instant"};
|
||||||
mStringMap["QuickSystemSelect"] = {"leftrightshoulders", "leftrightshoulders"};
|
mStringMap["QuickSystemSelect"] = {"leftrightshoulders", "leftrightshoulders"};
|
||||||
mStringMap["StartupSystem"] = {"", ""};
|
mStringMap["StartupSystem"] = {"", ""};
|
||||||
mStringMap["DefaultSortOrder"] = {"filename, ascending", "filename, ascending"};
|
mStringMap["DefaultSortOrder"] = {"filename, ascending", "filename, ascending"};
|
||||||
|
@ -323,6 +329,19 @@ void Settings::setDefaults()
|
||||||
mBoolMap["DebugText"] = {false, false};
|
mBoolMap["DebugText"] = {false, false};
|
||||||
mBoolMap["DebugImage"] = {false, false};
|
mBoolMap["DebugImage"] = {false, false};
|
||||||
mIntMap["ScraperFilter"] = {0, 0};
|
mIntMap["ScraperFilter"] = {0, 0};
|
||||||
|
|
||||||
|
mIntMap["TransitionsSystemToSystem"] = {ViewTransitionAnimation::INSTANT,
|
||||||
|
ViewTransitionAnimation::INSTANT};
|
||||||
|
mIntMap["TransitionsSystemToGamelist"] = {ViewTransitionAnimation::INSTANT,
|
||||||
|
ViewTransitionAnimation::INSTANT};
|
||||||
|
mIntMap["TransitionsGamelistToGamelist"] = {ViewTransitionAnimation::INSTANT,
|
||||||
|
ViewTransitionAnimation::INSTANT};
|
||||||
|
mIntMap["TransitionsGamelistToSystem"] = {ViewTransitionAnimation::INSTANT,
|
||||||
|
ViewTransitionAnimation::INSTANT};
|
||||||
|
mIntMap["TransitionsStartupToSystem"] = {ViewTransitionAnimation::INSTANT,
|
||||||
|
ViewTransitionAnimation::INSTANT};
|
||||||
|
mIntMap["TransitionsStartupToGamelist"] = {ViewTransitionAnimation::INSTANT,
|
||||||
|
ViewTransitionAnimation::INSTANT};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::saveFile()
|
void Settings::saveFile()
|
||||||
|
|
|
@ -40,6 +40,19 @@ std::vector<std::string> ThemeData::sSupportedMediaTypes {
|
||||||
{"fanart"},
|
{"fanart"},
|
||||||
{"video"}};
|
{"video"}};
|
||||||
|
|
||||||
|
std::vector<std::string> ThemeData::sSupportedTransitions {
|
||||||
|
{"systemToSystem"},
|
||||||
|
{"systemToGamelist"},
|
||||||
|
{"gamelistToGamelist"},
|
||||||
|
{"gamelistToSystem"},
|
||||||
|
{"startupToSystem"},
|
||||||
|
{"startupToGamelist"}};
|
||||||
|
|
||||||
|
std::vector<std::string> ThemeData::sSupportedTransitionAnimations {
|
||||||
|
{"builtin-instant"},
|
||||||
|
{"builtin-slide"},
|
||||||
|
{"builtin-fade"}};
|
||||||
|
|
||||||
std::vector<std::string> ThemeData::sLegacySupportedViews {
|
std::vector<std::string> ThemeData::sLegacySupportedViews {
|
||||||
{"all"},
|
{"all"},
|
||||||
{"system"},
|
{"system"},
|
||||||
|
@ -495,6 +508,7 @@ ThemeData::ThemeData()
|
||||||
, mCustomCollection {false}
|
, mCustomCollection {false}
|
||||||
{
|
{
|
||||||
mCurrentThemeSet = mThemeSets.find(Settings::getInstance()->getString("ThemeSet"));
|
mCurrentThemeSet = mThemeSets.find(Settings::getInstance()->getString("ThemeSet"));
|
||||||
|
mVariantDefinedTransitions = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeData::loadFile(const std::map<std::string, std::string>& sysDataMap,
|
void ThemeData::loadFile(const std::map<std::string, std::string>& sysDataMap,
|
||||||
|
@ -819,6 +833,95 @@ const std::string ThemeData::getAspectRatioLabel(const std::string& aspectRatio)
|
||||||
return "invalid ratio";
|
return "invalid ratio";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThemeData::setThemeTransitions()
|
||||||
|
{
|
||||||
|
auto setTransitionsFunc = [](int transitionAnim) {
|
||||||
|
Settings::getInstance()->setInt("TransitionsSystemToSystem", transitionAnim);
|
||||||
|
Settings::getInstance()->setInt("TransitionsSystemToGamelist", transitionAnim);
|
||||||
|
Settings::getInstance()->setInt("TransitionsGamelistToGamelist", transitionAnim);
|
||||||
|
Settings::getInstance()->setInt("TransitionsGamelistToSystem", transitionAnim);
|
||||||
|
Settings::getInstance()->setInt("TransitionsStartupToSystem", transitionAnim);
|
||||||
|
Settings::getInstance()->setInt("TransitionsStartupToGamelist", transitionAnim);
|
||||||
|
};
|
||||||
|
|
||||||
|
int transitionAnim {ViewTransitionAnimation::INSTANT};
|
||||||
|
setTransitionsFunc(transitionAnim);
|
||||||
|
|
||||||
|
if (mCurrentThemeSet->second.capabilities.legacyTheme) {
|
||||||
|
const std::string& legacyTransitionSetting {
|
||||||
|
Settings::getInstance()->getString("LegacyTransitionAnimations")};
|
||||||
|
if (legacyTransitionSetting == "builtin-slide")
|
||||||
|
transitionAnim = static_cast<int>(ViewTransitionAnimation::SLIDE);
|
||||||
|
else if (legacyTransitionSetting == "builtin-fade")
|
||||||
|
transitionAnim = static_cast<int>(ViewTransitionAnimation::FADE);
|
||||||
|
setTransitionsFunc(transitionAnim);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const std::string& transitionSetting {
|
||||||
|
Settings::getInstance()->getString("ThemeTransitionAnimations")};
|
||||||
|
std::string profile;
|
||||||
|
size_t profileEntry {0};
|
||||||
|
|
||||||
|
if (transitionSetting == "automatic") {
|
||||||
|
if (mVariantDefinedTransitions != "")
|
||||||
|
profile = mVariantDefinedTransitions;
|
||||||
|
else if (!mCurrentThemeSet->second.capabilities.transitions.empty())
|
||||||
|
profile = mCurrentThemeSet->second.capabilities.transitions.front().name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
profile = transitionSetting;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = std::find_if(
|
||||||
|
mCurrentThemeSet->second.capabilities.transitions.cbegin(),
|
||||||
|
mCurrentThemeSet->second.capabilities.transitions.cend(),
|
||||||
|
[&profile](const ThemeTransitions transitions) { return transitions.name == profile; });
|
||||||
|
if (it != mCurrentThemeSet->second.capabilities.transitions.cend())
|
||||||
|
profileEntry = static_cast<size_t>(
|
||||||
|
std::distance(mCurrentThemeSet->second.capabilities.transitions.cbegin(), it) + 1);
|
||||||
|
|
||||||
|
if (profileEntry != 0 &&
|
||||||
|
mCurrentThemeSet->second.capabilities.transitions.size() > profileEntry - 1) {
|
||||||
|
auto transitionMap =
|
||||||
|
mCurrentThemeSet->second.capabilities.transitions[profileEntry - 1].animations;
|
||||||
|
if (transitionMap.find(ViewTransition::SYSTEM_TO_SYSTEM) != transitionMap.end())
|
||||||
|
Settings::getInstance()->setInt("TransitionsSystemToSystem",
|
||||||
|
transitionMap[ViewTransition::SYSTEM_TO_SYSTEM]);
|
||||||
|
if (transitionMap.find(ViewTransition::SYSTEM_TO_GAMELIST) != transitionMap.end())
|
||||||
|
Settings::getInstance()->setInt("TransitionsSystemToGamelist",
|
||||||
|
transitionMap[ViewTransition::SYSTEM_TO_GAMELIST]);
|
||||||
|
if (transitionMap.find(ViewTransition::GAMELIST_TO_GAMELIST) != transitionMap.end())
|
||||||
|
Settings::getInstance()->setInt(
|
||||||
|
"TransitionsGamelistToGamelist",
|
||||||
|
transitionMap[ViewTransition::GAMELIST_TO_GAMELIST]);
|
||||||
|
if (transitionMap.find(ViewTransition::GAMELIST_TO_SYSTEM) != transitionMap.end())
|
||||||
|
Settings::getInstance()->setInt("TransitionsGamelistToSystem",
|
||||||
|
transitionMap[ViewTransition::GAMELIST_TO_SYSTEM]);
|
||||||
|
if (transitionMap.find(ViewTransition::STARTUP_TO_SYSTEM) != transitionMap.end())
|
||||||
|
Settings::getInstance()->setInt("TransitionsStartupToSystem",
|
||||||
|
transitionMap[ViewTransition::STARTUP_TO_SYSTEM]);
|
||||||
|
if (transitionMap.find(ViewTransition::STARTUP_TO_GAMELIST) != transitionMap.end())
|
||||||
|
Settings::getInstance()->setInt("TransitionsStartupToGamelist",
|
||||||
|
transitionMap[ViewTransition::STARTUP_TO_GAMELIST]);
|
||||||
|
}
|
||||||
|
else if (transitionSetting == "builtin-slide" || transitionSetting == "builtin-fade") {
|
||||||
|
if (std::find(
|
||||||
|
mCurrentThemeSet->second.capabilities.suppressedTransitionEntries.cbegin(),
|
||||||
|
mCurrentThemeSet->second.capabilities.suppressedTransitionEntries.cend(),
|
||||||
|
transitionSetting) ==
|
||||||
|
mCurrentThemeSet->second.capabilities.suppressedTransitionEntries.cend()) {
|
||||||
|
if (transitionSetting == "builtin-slide") {
|
||||||
|
transitionAnim = static_cast<int>(ViewTransitionAnimation::SLIDE);
|
||||||
|
}
|
||||||
|
else if (transitionSetting == "builtin-fade") {
|
||||||
|
transitionAnim = static_cast<int>(ViewTransitionAnimation::FADE);
|
||||||
|
}
|
||||||
|
setTransitionsFunc(transitionAnim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const std::map<ThemeTriggers::TriggerType, std::pair<std::string, std::vector<std::string>>>
|
const std::map<ThemeTriggers::TriggerType, std::pair<std::string, std::vector<std::string>>>
|
||||||
ThemeData::getCurrentThemeSetSelectedVariantOverrides()
|
ThemeData::getCurrentThemeSetSelectedVariantOverrides()
|
||||||
{
|
{
|
||||||
|
@ -1128,6 +1231,140 @@ ThemeData::ThemeCapability ThemeData::parseThemeCapabilities(const std::string&
|
||||||
capabilities.colorSchemes.emplace_back(readColorScheme);
|
capabilities.colorSchemes.emplace_back(readColorScheme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (pugi::xml_node transitions {themeCapabilities.child("transitions")}; transitions;
|
||||||
|
transitions = transitions.next_sibling("transitions")) {
|
||||||
|
std::map<ViewTransition, ViewTransitionAnimation> readTransitions;
|
||||||
|
std::string name {transitions.attribute("name").as_string()};
|
||||||
|
std::string label;
|
||||||
|
bool selectable {true};
|
||||||
|
|
||||||
|
if (name.empty()) {
|
||||||
|
LOG(LogWarning)
|
||||||
|
<< "Found <transitions> tag without name attribute, ignoring entry in \""
|
||||||
|
<< capFile << "\"";
|
||||||
|
name.clear();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (std::find(sSupportedTransitionAnimations.cbegin(),
|
||||||
|
sSupportedTransitionAnimations.cend(),
|
||||||
|
name) != sSupportedTransitionAnimations.cend()) {
|
||||||
|
LOG(LogWarning)
|
||||||
|
<< "Found <transitions> tag using reserved name attribute value \"" << name
|
||||||
|
<< "\", ignoring entry in \"" << capFile << "\"";
|
||||||
|
name.clear();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (auto& transitionEntry : capabilities.transitions) {
|
||||||
|
if (transitionEntry.name == name) {
|
||||||
|
LOG(LogWarning)
|
||||||
|
<< "Found <transitions> tag with previously used name attribute "
|
||||||
|
"value \""
|
||||||
|
<< name << "\", ignoring entry in \"" << capFile << "\"";
|
||||||
|
name.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == "")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const pugi::xml_node& labelTag {transitions.child("label")};
|
||||||
|
if (labelTag != nullptr)
|
||||||
|
label = labelTag.text().as_string();
|
||||||
|
|
||||||
|
const pugi::xml_node& selectableTag {transitions.child("selectable")};
|
||||||
|
if (selectableTag != nullptr) {
|
||||||
|
const std::string& value {selectableTag.text().as_string()};
|
||||||
|
if (value.front() == '0' || value.front() == 'f' || value.front() == 'F' ||
|
||||||
|
value.front() == 'n' || value.front() == 'N')
|
||||||
|
selectable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& currTransition : sSupportedTransitions) {
|
||||||
|
const pugi::xml_node& transitionTag {transitions.child(currTransition.c_str())};
|
||||||
|
if (transitionTag != nullptr) {
|
||||||
|
const std::string& transitionValue {transitionTag.text().as_string()};
|
||||||
|
if (transitionValue.empty()) {
|
||||||
|
LOG(LogWarning) << "Found <" << currTransition
|
||||||
|
<< "> transition tag without any value, "
|
||||||
|
"ignoring entry in \""
|
||||||
|
<< capFile << "\"";
|
||||||
|
}
|
||||||
|
else if (std::find(sSupportedTransitionAnimations.cbegin(),
|
||||||
|
sSupportedTransitionAnimations.cend(),
|
||||||
|
currTransition) != sSupportedTransitionAnimations.cend()) {
|
||||||
|
LOG(LogWarning)
|
||||||
|
<< "Invalid <" << currTransition << "> transition tag value \""
|
||||||
|
<< transitionValue << "\", ignoring entry in \"" << capFile << "\"";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ViewTransitionAnimation transitionAnim {ViewTransitionAnimation::INSTANT};
|
||||||
|
if (transitionValue == "slide")
|
||||||
|
transitionAnim = ViewTransitionAnimation::SLIDE;
|
||||||
|
else if (transitionValue == "fade")
|
||||||
|
transitionAnim = ViewTransitionAnimation::FADE;
|
||||||
|
|
||||||
|
if (currTransition == "systemToSystem")
|
||||||
|
readTransitions[ViewTransition::SYSTEM_TO_SYSTEM] = transitionAnim;
|
||||||
|
else if (currTransition == "systemToGamelist")
|
||||||
|
readTransitions[ViewTransition::SYSTEM_TO_GAMELIST] = transitionAnim;
|
||||||
|
else if (currTransition == "gamelistToGamelist")
|
||||||
|
readTransitions[ViewTransition::GAMELIST_TO_GAMELIST] = transitionAnim;
|
||||||
|
else if (currTransition == "gamelistToSystem")
|
||||||
|
readTransitions[ViewTransition::GAMELIST_TO_SYSTEM] = transitionAnim;
|
||||||
|
else if (currTransition == "startupToSystem")
|
||||||
|
readTransitions[ViewTransition::STARTUP_TO_SYSTEM] = transitionAnim;
|
||||||
|
else if (currTransition == "startupToGamelist")
|
||||||
|
readTransitions[ViewTransition::STARTUP_TO_GAMELIST] = transitionAnim;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!readTransitions.empty()) {
|
||||||
|
ThemeTransitions transition;
|
||||||
|
transition.name = name;
|
||||||
|
transition.label = label;
|
||||||
|
transition.selectable = selectable;
|
||||||
|
transition.animations = std::move(readTransitions);
|
||||||
|
capabilities.transitions.emplace_back(std::move(transition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (pugi::xml_node suppressTransitionEntries {
|
||||||
|
themeCapabilities.child("suppressTransitionEntries")};
|
||||||
|
suppressTransitionEntries;
|
||||||
|
suppressTransitionEntries =
|
||||||
|
suppressTransitionEntries.next_sibling("suppressTransitionEntries")) {
|
||||||
|
std::vector<std::string> readSuppressEntries;
|
||||||
|
|
||||||
|
for (pugi::xml_node entries {suppressTransitionEntries.child("entry")}; entries;
|
||||||
|
entries = entries.next_sibling("entry")) {
|
||||||
|
const std::string& entryValue {entries.text().as_string()};
|
||||||
|
|
||||||
|
if (std::find(sSupportedTransitionAnimations.cbegin(),
|
||||||
|
sSupportedTransitionAnimations.cend(),
|
||||||
|
entryValue) != sSupportedTransitionAnimations.cend()) {
|
||||||
|
capabilities.suppressedTransitionEntries.emplace_back(entryValue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG(LogWarning)
|
||||||
|
<< "Found suppressTransitionEntries <entry> tag with invalid value \""
|
||||||
|
<< entryValue << "\", ignoring entry in \"" << capFile << "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort and remove any duplicates.
|
||||||
|
if (capabilities.suppressedTransitionEntries.size() > 1) {
|
||||||
|
std::sort(capabilities.suppressedTransitionEntries.begin(),
|
||||||
|
capabilities.suppressedTransitionEntries.end());
|
||||||
|
auto last = std::unique(capabilities.suppressedTransitionEntries.begin(),
|
||||||
|
capabilities.suppressedTransitionEntries.end());
|
||||||
|
capabilities.suppressedTransitionEntries.erase(
|
||||||
|
last, capabilities.suppressedTransitionEntries.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG(LogDebug) << "No capabilities.xml file found, flagging as legacy theme set";
|
LOG(LogDebug) << "No capabilities.xml file found, flagging as legacy theme set";
|
||||||
|
@ -1311,6 +1548,21 @@ void ThemeData::parseVariants(const pugi::xml_node& root)
|
||||||
mOverrideVariant};
|
mOverrideVariant};
|
||||||
|
|
||||||
if (variant == viewKey || viewKey == "all") {
|
if (variant == viewKey || viewKey == "all") {
|
||||||
|
const pugi::xml_node& transitions {node.child("transitions")};
|
||||||
|
if (transitions != nullptr) {
|
||||||
|
const std::string& transitionsValue {transitions.text().as_string()};
|
||||||
|
if (std::find_if(mCurrentThemeSet->second.capabilities.transitions.cbegin(),
|
||||||
|
mCurrentThemeSet->second.capabilities.transitions.cend(),
|
||||||
|
[&transitionsValue](const ThemeTransitions transitions) {
|
||||||
|
return transitions.name == transitionsValue;
|
||||||
|
}) ==
|
||||||
|
mCurrentThemeSet->second.capabilities.transitions.cend()) {
|
||||||
|
throw error << ": <transitions> value \"" << transitionsValue
|
||||||
|
<< "\" is not matching any defined transitions";
|
||||||
|
}
|
||||||
|
mVariantDefinedTransitions = transitionsValue;
|
||||||
|
}
|
||||||
|
|
||||||
parseVariables(node);
|
parseVariables(node);
|
||||||
parseColorSchemes(node);
|
parseColorSchemes(node);
|
||||||
parseIncludes(node);
|
parseIncludes(node);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#ifndef ES_CORE_THEME_DATA_H
|
#ifndef ES_CORE_THEME_DATA_H
|
||||||
#define ES_CORE_THEME_DATA_H
|
#define ES_CORE_THEME_DATA_H
|
||||||
|
|
||||||
|
#include "GuiComponent.h"
|
||||||
#include "utils/FileSystemUtil.h"
|
#include "utils/FileSystemUtil.h"
|
||||||
#include "utils/MathUtil.h"
|
#include "utils/MathUtil.h"
|
||||||
#include "utils/StringUtil.h"
|
#include "utils/StringUtil.h"
|
||||||
|
@ -198,10 +199,24 @@ public:
|
||||||
std::string label;
|
std::string label;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ThemeTransitions {
|
||||||
|
std::string name;
|
||||||
|
std::string label;
|
||||||
|
bool selectable;
|
||||||
|
std::map<ViewTransition, ViewTransitionAnimation> animations;
|
||||||
|
|
||||||
|
ThemeTransitions()
|
||||||
|
: selectable {true}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct ThemeCapability {
|
struct ThemeCapability {
|
||||||
std::vector<ThemeVariant> variants;
|
std::vector<ThemeVariant> variants;
|
||||||
std::vector<ThemeColorScheme> colorSchemes;
|
std::vector<ThemeColorScheme> colorSchemes;
|
||||||
std::vector<std::string> aspectRatios;
|
std::vector<std::string> aspectRatios;
|
||||||
|
std::vector<ThemeTransitions> transitions;
|
||||||
|
std::vector<std::string> suppressedTransitionEntries;
|
||||||
bool legacyTheme;
|
bool legacyTheme;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -245,6 +260,7 @@ public:
|
||||||
const static std::string getThemeFromCurrentSet(const std::string& system);
|
const static std::string getThemeFromCurrentSet(const std::string& system);
|
||||||
const static std::string getAspectRatioLabel(const std::string& aspectRatio);
|
const static std::string getAspectRatioLabel(const std::string& aspectRatio);
|
||||||
const static std::string getCurrentThemeSetName() { return mCurrentThemeSet->first; }
|
const static std::string getCurrentThemeSetName() { return mCurrentThemeSet->first; }
|
||||||
|
static void setThemeTransitions();
|
||||||
|
|
||||||
const bool isLegacyTheme() { return mLegacyTheme; }
|
const bool isLegacyTheme() { return mLegacyTheme; }
|
||||||
const std::map<ThemeTriggers::TriggerType, std::pair<std::string, std::vector<std::string>>>
|
const std::map<ThemeTriggers::TriggerType, std::pair<std::string, std::vector<std::string>>>
|
||||||
|
@ -291,6 +307,8 @@ private:
|
||||||
|
|
||||||
static std::vector<std::string> sSupportedViews;
|
static std::vector<std::string> sSupportedViews;
|
||||||
static std::vector<std::string> sSupportedMediaTypes;
|
static std::vector<std::string> sSupportedMediaTypes;
|
||||||
|
static std::vector<std::string> sSupportedTransitions;
|
||||||
|
static std::vector<std::string> sSupportedTransitionAnimations;
|
||||||
static std::vector<std::string> sLegacySupportedViews;
|
static std::vector<std::string> sLegacySupportedViews;
|
||||||
static std::vector<std::string> sLegacySupportedFeatures;
|
static std::vector<std::string> sLegacySupportedFeatures;
|
||||||
static std::vector<std::string> sLegacyProperties;
|
static std::vector<std::string> sLegacyProperties;
|
||||||
|
@ -302,6 +320,7 @@ private:
|
||||||
|
|
||||||
static inline std::map<std::string, ThemeSet, StringComparator> mThemeSets;
|
static inline std::map<std::string, ThemeSet, StringComparator> mThemeSets;
|
||||||
static inline std::map<std::string, ThemeSet, StringComparator>::iterator mCurrentThemeSet {};
|
static inline std::map<std::string, ThemeSet, StringComparator>::iterator mCurrentThemeSet {};
|
||||||
|
static inline std::string mVariantDefinedTransitions;
|
||||||
|
|
||||||
std::map<std::string, ThemeView> mViews;
|
std::map<std::string, ThemeView> mViews;
|
||||||
std::deque<std::string> mPaths;
|
std::deque<std::string> mPaths;
|
||||||
|
|
Loading…
Reference in a new issue