mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-29 19:55:37 +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"),
|
||||
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.
|
||||
auto gamelistViewStyle = std::make_shared<OptionListComponent<std::string>>(
|
||||
getHelpStyle(), "LEGACY GAMELIST VIEW STYLE", false);
|
||||
|
@ -318,21 +413,28 @@ void GuiMenu::openUIOptions()
|
|||
}
|
||||
});
|
||||
|
||||
// Legacy ransition style.
|
||||
auto transitionStyle = std::make_shared<OptionListComponent<std::string>>(
|
||||
getHelpStyle(), "LEGACY TRANSITION STYLE", false);
|
||||
std::vector<std::string> transitions;
|
||||
transitions.push_back("slide");
|
||||
transitions.push_back("fade");
|
||||
transitions.push_back("instant");
|
||||
for (auto it = transitions.cbegin(); it != transitions.cend(); ++it)
|
||||
transitionStyle->add(*it, *it,
|
||||
Settings::getInstance()->getString("TransitionStyle") == *it);
|
||||
s->addWithLabel("LEGACY TRANSITION STYLE", transitionStyle);
|
||||
s->addSaveFunc([transitionStyle, s] {
|
||||
if (transitionStyle->getSelected() !=
|
||||
Settings::getInstance()->getString("TransitionStyle")) {
|
||||
Settings::getInstance()->setString("TransitionStyle", transitionStyle->getSelected());
|
||||
// Legacy transition animations.
|
||||
auto legacyTransitionAnimations = std::make_shared<OptionListComponent<std::string>>(
|
||||
getHelpStyle(), "LEGACY TRANSITION ANIMS", false);
|
||||
const std::string& selectedLegacyAnimations {
|
||||
Settings::getInstance()->getString("LegacyTransitionAnimations")};
|
||||
legacyTransitionAnimations->add("INSTANT", "builtin-instant",
|
||||
selectedLegacyAnimations == "builtin-instant");
|
||||
legacyTransitionAnimations->add("SLIDE", "builtin-slide",
|
||||
selectedLegacyAnimations == "builtin-slide");
|
||||
legacyTransitionAnimations->add("FADE", "builtin-fade",
|
||||
selectedLegacyAnimations == "builtin-fade");
|
||||
// If there are no objects returned, then there must be a manually modified entry in the
|
||||
// configuration file. Simply set the animations to "builtin-instant" in this case.
|
||||
if (legacyTransitionAnimations->getSelectedObjects().size() == 0)
|
||||
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();
|
||||
}
|
||||
});
|
||||
|
@ -729,6 +831,7 @@ void GuiMenu::openUIOptions()
|
|||
themeVariantsFunc(themeName, themeVariant->getSelected());
|
||||
themeColorSchemesFunc(themeName, themeColorScheme->getSelected());
|
||||
themeAspectRatiosFunc(themeName, themeAspectRatio->getSelected());
|
||||
themeTransitionAnimationsFunc(themeName, themeTransitionAnimations->getSelected());
|
||||
}
|
||||
int selectableVariants {0};
|
||||
for (auto& variant : selectedSet->second.capabilities.variants) {
|
||||
|
@ -785,12 +888,18 @@ void GuiMenu::openUIOptions()
|
|||
gamelistViewStyle->getParent()
|
||||
->getChild(gamelistViewStyle->getChildIndex() - 1)
|
||||
->setOpacity(DISABLED_OPACITY);
|
||||
// TEMPORARY
|
||||
// transitionStyle->setEnabled(false);
|
||||
// transitionStyle->setOpacity(DISABLED_OPACITY);
|
||||
// transitionStyle->getParent()
|
||||
// ->getChild(transitionStyle->getChildIndex() - 1)
|
||||
// ->setOpacity(DISABLED_OPACITY);
|
||||
|
||||
themeTransitionAnimations->setEnabled(true);
|
||||
themeTransitionAnimations->setOpacity(1.0f);
|
||||
themeTransitionAnimations->getParent()
|
||||
->getChild(themeTransitionAnimations->getChildIndex() - 1)
|
||||
->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.
|
||||
gamelistVideoPillarbox->setEnabled(false);
|
||||
|
@ -813,10 +922,16 @@ void GuiMenu::openUIOptions()
|
|||
->getChild(gamelistViewStyle->getChildIndex() - 1)
|
||||
->setOpacity(1.0f);
|
||||
|
||||
transitionStyle->setEnabled(true);
|
||||
transitionStyle->setOpacity(1.0f);
|
||||
transitionStyle->getParent()
|
||||
->getChild(transitionStyle->getChildIndex() - 1)
|
||||
themeTransitionAnimations->setEnabled(false);
|
||||
themeTransitionAnimations->setOpacity(DISABLED_OPACITY);
|
||||
themeTransitionAnimations->getParent()
|
||||
->getChild(themeTransitionAnimations->getChildIndex() - 1)
|
||||
->setOpacity(DISABLED_OPACITY);
|
||||
|
||||
legacyTransitionAnimations->setEnabled(true);
|
||||
legacyTransitionAnimations->setOpacity(1.0f);
|
||||
legacyTransitionAnimations->getParent()
|
||||
->getChild(legacyTransitionAnimations->getChildIndex() - 1)
|
||||
->setOpacity(1.0f);
|
||||
|
||||
gamelistVideoPillarbox->setEnabled(true);
|
||||
|
|
|
@ -227,8 +227,9 @@ void SystemView::onCursorChanged(const CursorState& state)
|
|||
{
|
||||
const int cursor {mPrimary->getCursor()};
|
||||
const int scrollVelocity {mPrimary->getScrollingVelocity()};
|
||||
const std::string& transitionStyle {Settings::getInstance()->getString("TransitionStyle")};
|
||||
mFadeTransitions = transitionStyle == "fade";
|
||||
const ViewTransitionAnimation transitionAnim {static_cast<ViewTransitionAnimation>(
|
||||
Settings::getInstance()->getInt("TransitionsSystemToSystem"))};
|
||||
mFadeTransitions = (transitionAnim == ViewTransitionAnimation::FADE);
|
||||
|
||||
// Some logic needed to avoid various navigation glitches with GridComponent and
|
||||
// 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
|
||||
// slide transitions. This should very rarely occur during normal application usage.
|
||||
if (transitionStyle == "slide") {
|
||||
if (transitionAnim == ViewTransitionAnimation::SLIDE) {
|
||||
bool resetCamOffset {false};
|
||||
|
||||
if (scrollVelocity == -1 && mPreviousScrollVelocity == 1) {
|
||||
|
@ -372,7 +373,7 @@ void SystemView::onCursorChanged(const CursorState& state)
|
|||
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};
|
||||
anim = new LambdaAnimation(
|
||||
[this, startFade, endPos](float t) {
|
||||
|
@ -398,7 +399,7 @@ void SystemView::onCursorChanged(const CursorState& state)
|
|||
},
|
||||
static_cast<int>(animTime * 1.3f));
|
||||
}
|
||||
else if (transitionStyle == "slide") {
|
||||
else if (transitionAnim == ViewTransitionAnimation::SLIDE) {
|
||||
mUpdatedGameCount = false;
|
||||
anim = new LambdaAnimation(
|
||||
[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()
|
||||
|
|
|
@ -37,6 +37,7 @@ ViewController::ViewController() noexcept
|
|||
, mCurrentView {nullptr}
|
||||
, mPreviousView {nullptr}
|
||||
, mSkipView {nullptr}
|
||||
, mLastTransitionAnim {ViewTransitionAnimation::INSTANT}
|
||||
, mGameToLaunch {nullptr}
|
||||
, mCamera {Renderer::getIdentity()}
|
||||
, mSystemViewTransition {false}
|
||||
|
@ -220,7 +221,7 @@ void ViewController::goToStart(bool playTransition)
|
|||
|
||||
// If a specific system is requested, go directly to its game list.
|
||||
auto requestedSystem = Settings::getInstance()->getString("StartupSystem");
|
||||
if ("" != requestedSystem && "retropie" != requestedSystem) {
|
||||
if (requestedSystem != "") {
|
||||
for (auto it = SystemData::sSystemVector.cbegin(); // Line break.
|
||||
it != SystemData::sSystemVector.cend(); ++it) {
|
||||
if ((*it)->getName() == requestedSystem) {
|
||||
|
@ -263,7 +264,7 @@ bool ViewController::isCameraMoving()
|
|||
|
||||
void ViewController::cancelViewTransitions()
|
||||
{
|
||||
if (Settings::getInstance()->getString("TransitionStyle") == "slide") {
|
||||
if (mLastTransitionAnim == ViewTransitionAnimation::SLIDE) {
|
||||
if (isCameraMoving()) {
|
||||
mCamera[3].x = -mCurrentView->getPosition().x;
|
||||
mCamera[3].y = -mCurrentView->getPosition().y;
|
||||
|
@ -277,7 +278,7 @@ void ViewController::cancelViewTransitions()
|
|||
mSkipView = nullptr;
|
||||
}
|
||||
}
|
||||
else if (Settings::getInstance()->getString("TransitionStyle") == "fade") {
|
||||
else if (mLastTransitionAnim == ViewTransitionAnimation::FADE) {
|
||||
if (isAnimationPlaying(0)) {
|
||||
finishAnimation(0);
|
||||
mCancelledTransition = true;
|
||||
|
@ -354,8 +355,11 @@ void ViewController::goToSystemView(SystemData* system, bool playTransition)
|
|||
|
||||
// Application startup animation.
|
||||
if (applicationStartup) {
|
||||
const ViewTransitionAnimation transitionAnim {static_cast<ViewTransitionAnimation>(
|
||||
Settings::getInstance()->getInt("TransitionsStartupToSystem"))};
|
||||
|
||||
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()->getCarouselType() ==
|
||||
CarouselComponent<SystemData*>::CarouselType::HORIZONTAL ||
|
||||
|
@ -370,7 +374,7 @@ void ViewController::goToSystemView(SystemData* system, bool playTransition)
|
|||
}
|
||||
updateHelpPrompts();
|
||||
}
|
||||
else if (Settings::getInstance()->getString("TransitionStyle") == "fade") {
|
||||
else if (transitionAnim == ViewTransitionAnimation::FADE) {
|
||||
if (getSystemListView()->getPrimaryType() == SystemView::PrimaryType::CAROUSEL) {
|
||||
if (getSystemListView()->getCarouselType() ==
|
||||
CarouselComponent<SystemData*>::CarouselType::HORIZONTAL ||
|
||||
|
@ -389,18 +393,21 @@ void ViewController::goToSystemView(SystemData* system, bool playTransition)
|
|||
}
|
||||
}
|
||||
|
||||
if (applicationStartup) {
|
||||
#if defined(__APPLE__)
|
||||
// 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.
|
||||
if (applicationStartup)
|
||||
playViewTransition(true);
|
||||
else if (playTransition)
|
||||
// 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.
|
||||
playViewTransition(ViewTransition::STARTUP_TO_SYSTEM, true);
|
||||
#else
|
||||
if (playTransition || applicationStartup)
|
||||
playViewTransition(ViewTransition::STARTUP_TO_SYSTEM);
|
||||
#endif
|
||||
playViewTransition();
|
||||
else
|
||||
playViewTransition(true);
|
||||
}
|
||||
else if (playTransition) {
|
||||
playViewTransition(ViewTransition::GAMELIST_TO_SYSTEM);
|
||||
}
|
||||
else {
|
||||
playViewTransition(ViewTransition::GAMELIST_TO_SYSTEM, true);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewController::goToSystem(SystemData* system, bool animate)
|
||||
|
@ -433,21 +440,37 @@ void ViewController::goToGamelist(SystemData* system)
|
|||
bool wrapFirstToLast {false};
|
||||
bool wrapLastToFirst {false};
|
||||
bool slideTransitions {false};
|
||||
bool fadeTransitions {false};
|
||||
|
||||
if (mCurrentView != nullptr)
|
||||
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;
|
||||
|
||||
if (transitionAnim == ViewTransitionAnimation::FADE)
|
||||
fadeTransitions = true;
|
||||
|
||||
// Restore the X position for the view, if it was previously moved.
|
||||
if (mWrappedViews)
|
||||
restoreViewPosition();
|
||||
|
||||
if (mPreviousView && Settings::getInstance()->getString("TransitionStyle") == "fade" &&
|
||||
isAnimationPlaying(0)) {
|
||||
if (mPreviousView && fadeTransitions && isAnimationPlaying(0))
|
||||
mPreviousView->onHide();
|
||||
}
|
||||
|
||||
if (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.
|
||||
if (mState.viewing == NOTHING) {
|
||||
if (mLastTransitionAnim == ViewTransitionAnimation::FADE)
|
||||
cancelViewTransitions();
|
||||
transitionType = ViewTransition::STARTUP_TO_GAMELIST;
|
||||
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();
|
||||
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;
|
||||
}
|
||||
else {
|
||||
|
@ -570,14 +598,14 @@ void ViewController::goToGamelist(SystemData* system)
|
|||
if (mCurrentView)
|
||||
mCurrentView->onShow();
|
||||
|
||||
playViewTransition();
|
||||
playViewTransition(transitionType);
|
||||
}
|
||||
|
||||
void ViewController::playViewTransition(bool instant)
|
||||
void ViewController::playViewTransition(ViewTransition transitionType, bool instant)
|
||||
{
|
||||
mCancelledTransition = false;
|
||||
|
||||
glm::vec3 target {};
|
||||
glm::vec3 target {0.0f, 0.0f, 0.0f};
|
||||
if (mCurrentView)
|
||||
target = mCurrentView->getPosition();
|
||||
|
||||
|
@ -586,9 +614,30 @@ void ViewController::playViewTransition(bool instant)
|
|||
if (target == static_cast<glm::vec3>(-mCamera[3]) && !isAnimationPlaying(0))
|
||||
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(
|
||||
[this, target](float /*t*/) {
|
||||
this->mCamera[3].x = -target.x;
|
||||
|
@ -600,7 +649,7 @@ void ViewController::playViewTransition(bool instant)
|
|||
1));
|
||||
updateHelpPrompts();
|
||||
}
|
||||
else if (transition_style == "fade") {
|
||||
else if (transitionAnim == ViewTransitionAnimation::FADE) {
|
||||
// Stop whatever's currently playing, leaving mFadeOpacity wherever it is.
|
||||
cancelAnimation(0);
|
||||
|
||||
|
@ -641,7 +690,7 @@ void ViewController::playViewTransition(bool instant)
|
|||
advanceAnimation(0, static_cast<int>(mFadeOpacity * FADE_DURATION));
|
||||
}
|
||||
}
|
||||
else if (transition_style == "slide") {
|
||||
else if (transitionAnim == ViewTransitionAnimation::SLIDE) {
|
||||
auto slideCallback = [this]() {
|
||||
if (mSkipView) {
|
||||
mSkipView->onHide();
|
||||
|
@ -1046,7 +1095,7 @@ void ViewController::render(const glm::mat4& parentTrans)
|
|||
|
||||
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.
|
||||
if (!SystemData::sSystemVector.empty())
|
||||
|
@ -1064,6 +1113,8 @@ void ViewController::preload()
|
|||
getGamelistView(*it)->preloadGamelist();
|
||||
}
|
||||
|
||||
ThemeData::setThemeTransitions();
|
||||
|
||||
// Load navigation sounds, either from the theme if it supports it, or otherwise from
|
||||
// the bundled fallback sound files.
|
||||
bool themeSoundSupport {false};
|
||||
|
@ -1082,7 +1133,7 @@ void ViewController::reloadGamelistView(GamelistView* view, bool reloadTheme)
|
|||
{
|
||||
for (auto it = mGamelistViews.cbegin(); it != mGamelistViews.cend(); ++it) {
|
||||
if (it->second.get() == view) {
|
||||
bool isCurrent {(mCurrentView == it->second)};
|
||||
bool isCurrent {mCurrentView == it->second};
|
||||
SystemData* system {it->first};
|
||||
FileData* cursor {view->getCursor()};
|
||||
|
||||
|
@ -1147,6 +1198,8 @@ void ViewController::reloadAll()
|
|||
it->first->getIndex()->resetFilters();
|
||||
}
|
||||
|
||||
ThemeData::setThemeTransitions();
|
||||
|
||||
// Rebuild SystemListView.
|
||||
mSystemListView.reset();
|
||||
getSystemListView();
|
||||
|
@ -1160,7 +1213,7 @@ void ViewController::reloadAll()
|
|||
mCurrentView = getGamelistView(mState.getSystem());
|
||||
}
|
||||
else if (mState.viewing == SYSTEM_SELECT) {
|
||||
SystemData* system = mState.getSystem();
|
||||
SystemData* system {mState.getSystem()};
|
||||
mSystemListView->goToSystem(system, false);
|
||||
mCurrentView = mSystemListView;
|
||||
mCamera[3].x = 0.0f;
|
||||
|
|
|
@ -160,7 +160,7 @@ private:
|
|||
std::string mRomDirectory;
|
||||
GuiMsgBox* mNoGamesMessageBox;
|
||||
|
||||
void playViewTransition(bool instant = false);
|
||||
void playViewTransition(ViewTransition transitionType, bool instant = false);
|
||||
int getSystemId(SystemData* system);
|
||||
// Restore view position if it was moved during wrap around.
|
||||
void restoreViewPosition();
|
||||
|
@ -170,6 +170,7 @@ private:
|
|||
std::shared_ptr<GuiComponent> mSkipView;
|
||||
std::map<SystemData*, std::shared_ptr<GamelistView>> mGamelistViews;
|
||||
std::shared_ptr<SystemView> mSystemListView;
|
||||
ViewTransitionAnimation mLastTransitionAnim;
|
||||
|
||||
std::vector<std::string> mGameEndEventParams;
|
||||
FileData* mGameToLaunch;
|
||||
|
|
|
@ -34,6 +34,21 @@ class InputConfig;
|
|||
class ThemeData;
|
||||
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 {
|
||||
ALIGN_LEFT,
|
||||
ALIGN_CENTER, // Used for both horizontal and vertical alignments.
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "Settings.h"
|
||||
|
||||
#include "GuiComponent.h"
|
||||
#include "Log.h"
|
||||
#include "Scripting.h"
|
||||
#include "utils/FileSystemUtil.h"
|
||||
|
@ -20,10 +21,8 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
// These values are NOT saved to es_settings.xml since they're not set via
|
||||
// the in-program settings menu. Most can be set using command-line arguments,
|
||||
// but some are debug flags that are either hardcoded or set by internal debug
|
||||
// functions.
|
||||
// These settings are not saved to es_settings.xml. Most can be set using command-line
|
||||
// arguments but a couple are debug flags or used for other application-internal purposes.
|
||||
std::vector<std::string> settingsSkipSaving {
|
||||
// clang-format off
|
||||
// These options can be set using command-line arguments:
|
||||
|
@ -38,18 +37,24 @@ namespace
|
|||
"ForceKiosk", // --force-kiosk
|
||||
"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:
|
||||
"ScreenWidth", // Set via --screensize [width] [height]
|
||||
"ScreenHeight", // set via --screensize [width] [height]
|
||||
"ScreenOffsetX", // 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",
|
||||
"DebugText",
|
||||
"DebugImage",
|
||||
"ScraperFilter"
|
||||
"ScraperFilter",
|
||||
"TransitionsSystemToSystem",
|
||||
"TransitionsSystemToGamelist",
|
||||
"TransitionsGamelistToGamelist",
|
||||
"TransitionsGamelistToSystem",
|
||||
"TransitionsStartupToSystem",
|
||||
"TransitionsStartupToGamelist"
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
@ -151,8 +156,9 @@ void Settings::setDefaults()
|
|||
mStringMap["ThemeVariant"] = {"", ""};
|
||||
mStringMap["ThemeColorScheme"] = {"", ""};
|
||||
mStringMap["ThemeAspectRatio"] = {"", ""};
|
||||
mStringMap["ThemeTransitionAnimations"] = {"automatic", "automatic"};
|
||||
mStringMap["GamelistViewStyle"] = {"automatic", "automatic"};
|
||||
mStringMap["TransitionStyle"] = {"slide", "slide"};
|
||||
mStringMap["LegacyTransitionAnimations"] = {"builtin-instant", "builtin-instant"};
|
||||
mStringMap["QuickSystemSelect"] = {"leftrightshoulders", "leftrightshoulders"};
|
||||
mStringMap["StartupSystem"] = {"", ""};
|
||||
mStringMap["DefaultSortOrder"] = {"filename, ascending", "filename, ascending"};
|
||||
|
@ -323,6 +329,19 @@ void Settings::setDefaults()
|
|||
mBoolMap["DebugText"] = {false, false};
|
||||
mBoolMap["DebugImage"] = {false, false};
|
||||
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()
|
||||
|
|
|
@ -40,6 +40,19 @@ std::vector<std::string> ThemeData::sSupportedMediaTypes {
|
|||
{"fanart"},
|
||||
{"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 {
|
||||
{"all"},
|
||||
{"system"},
|
||||
|
@ -495,6 +508,7 @@ ThemeData::ThemeData()
|
|||
, mCustomCollection {false}
|
||||
{
|
||||
mCurrentThemeSet = mThemeSets.find(Settings::getInstance()->getString("ThemeSet"));
|
||||
mVariantDefinedTransitions = "";
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
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>>>
|
||||
ThemeData::getCurrentThemeSetSelectedVariantOverrides()
|
||||
{
|
||||
|
@ -1128,6 +1231,140 @@ ThemeData::ThemeCapability ThemeData::parseThemeCapabilities(const std::string&
|
|||
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 {
|
||||
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};
|
||||
|
||||
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);
|
||||
parseColorSchemes(node);
|
||||
parseIncludes(node);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#ifndef ES_CORE_THEME_DATA_H
|
||||
#define ES_CORE_THEME_DATA_H
|
||||
|
||||
#include "GuiComponent.h"
|
||||
#include "utils/FileSystemUtil.h"
|
||||
#include "utils/MathUtil.h"
|
||||
#include "utils/StringUtil.h"
|
||||
|
@ -198,10 +199,24 @@ public:
|
|||
std::string label;
|
||||
};
|
||||
|
||||
struct ThemeTransitions {
|
||||
std::string name;
|
||||
std::string label;
|
||||
bool selectable;
|
||||
std::map<ViewTransition, ViewTransitionAnimation> animations;
|
||||
|
||||
ThemeTransitions()
|
||||
: selectable {true}
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct ThemeCapability {
|
||||
std::vector<ThemeVariant> variants;
|
||||
std::vector<ThemeColorScheme> colorSchemes;
|
||||
std::vector<std::string> aspectRatios;
|
||||
std::vector<ThemeTransitions> transitions;
|
||||
std::vector<std::string> suppressedTransitionEntries;
|
||||
bool legacyTheme;
|
||||
};
|
||||
|
||||
|
@ -245,6 +260,7 @@ public:
|
|||
const static std::string getThemeFromCurrentSet(const std::string& system);
|
||||
const static std::string getAspectRatioLabel(const std::string& aspectRatio);
|
||||
const static std::string getCurrentThemeSetName() { return mCurrentThemeSet->first; }
|
||||
static void setThemeTransitions();
|
||||
|
||||
const bool isLegacyTheme() { return mLegacyTheme; }
|
||||
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> sSupportedMediaTypes;
|
||||
static std::vector<std::string> sSupportedTransitions;
|
||||
static std::vector<std::string> sSupportedTransitionAnimations;
|
||||
static std::vector<std::string> sLegacySupportedViews;
|
||||
static std::vector<std::string> sLegacySupportedFeatures;
|
||||
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>::iterator mCurrentThemeSet {};
|
||||
static inline std::string mVariantDefinedTransitions;
|
||||
|
||||
std::map<std::string, ThemeView> mViews;
|
||||
std::deque<std::string> mPaths;
|
||||
|
|
Loading…
Reference in a new issue