Added a 'stationary' property to all secondary elements to set them as stationary during slide transitions

Also changed the view mode enum to an enum class
This commit is contained in:
Leon Styhre 2023-08-06 23:51:53 +02:00
parent fa1c5331a0
commit a4ba7de722
16 changed files with 376 additions and 73 deletions

View file

@ -177,7 +177,7 @@ bool GamelistBase::input(InputConfig* config, Input input)
mRoot->getSystem()->getThemeFolder() == "custom-collections" &&
mCursorStack.empty() &&
ViewController::getInstance()->getState().viewing ==
ViewController::GAMELIST) {
ViewController::ViewMode::GAMELIST) {
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
// Jump to the randomly selected game.
if (mRandomGame) {
@ -233,7 +233,8 @@ bool GamelistBase::input(InputConfig* config, Input input)
else if (config->isMappedTo("y", input) &&
mRoot->getSystem()->getThemeFolder() == "custom-collections" &&
!CollectionSystemsManager::getInstance()->isEditing() && mCursorStack.empty() &&
ViewController::getInstance()->getState().viewing == ViewController::GAMELIST) {
ViewController::getInstance()->getState().viewing ==
ViewController::ViewMode::GAMELIST) {
// Jump to the randomly selected game.
if (mRandomGame) {
NavigationSounds::getInstance().playThemeNavigationSound(SELECTSOUND);

View file

@ -400,12 +400,77 @@ void GamelistView::render(const glm::mat4& parentTrans)
glm::mat4 trans {parentTrans * getTransform()};
// Make sure nothing renders outside our designated area.
mRenderer->pushClipRect(
glm::ivec2 {static_cast<int>(std::round(trans[3].x)),
static_cast<int>(std::round(trans[3].y))},
glm::ivec2 {static_cast<int>(std::round(mSize.x)), static_cast<int>(std::round(mSize.y))});
auto clipRectFunc = [this, trans]() {
mRenderer->pushClipRect(glm::ivec2 {static_cast<int>(std::round(trans[3].x)),
static_cast<int>(std::round(trans[3].y))},
glm::ivec2 {static_cast<int>(std::round(mSize.x)),
static_cast<int>(std::round(mSize.y))});
};
clipRectFunc();
const ViewController::State viewState {ViewController::getInstance()->getState()};
bool stationaryApplicable {false};
// If it's the startup animation, then don't apply stationary properties.
if (viewState.previouslyViewed == ViewController::ViewMode::NOTHING)
stationaryApplicable = false;
// If it's a gamelist to gamelist transition and these animations are set to slide.
if (static_cast<ViewTransitionAnimation>(Settings::getInstance()->getInt(
"TransitionsGamelistToGamelist")) == ViewTransitionAnimation::SLIDE &&
viewState.viewing == ViewController::ViewMode::GAMELIST &&
viewState.previouslyViewed == ViewController::ViewMode::GAMELIST)
stationaryApplicable = true;
// If it's a gamelist to system transition and these animations are set to slide.
if (static_cast<ViewTransitionAnimation>(Settings::getInstance()->getInt(
"TransitionsGamelistToSystem")) == ViewTransitionAnimation::SLIDE &&
viewState.viewing == ViewController::ViewMode::SYSTEM_SELECT)
stationaryApplicable = true;
// If it's a system to gamelist transition and these animations are set to slide.
if (static_cast<ViewTransitionAnimation>(Settings::getInstance()->getInt(
"TransitionsSystemToGamelist")) == ViewTransitionAnimation::SLIDE &&
viewState.previouslyViewed == ViewController::ViewMode::SYSTEM_SELECT)
stationaryApplicable = true;
for (unsigned int i {0}; i < getChildCount(); ++i) {
bool childStationary {false};
if (stationaryApplicable) {
if (getChild(i)->getStationary() == Stationary::NEVER) {
childStationary = false;
}
else if (viewState.viewing == ViewController::ViewMode::GAMELIST &&
viewState.previouslyViewed == ViewController::ViewMode::GAMELIST &&
(getChild(i)->getStationary() == Stationary::WITHIN_VIEW ||
getChild(i)->getStationary() == Stationary::ALWAYS)) {
childStationary = true;
}
else if (viewState.viewing == ViewController::ViewMode::SYSTEM_SELECT &&
(getChild(i)->getStationary() == Stationary::BETWEEN_VIEWS ||
getChild(i)->getStationary() == Stationary::ALWAYS)) {
childStationary = true;
}
else if (viewState.previouslyViewed == ViewController::ViewMode::SYSTEM_SELECT &&
(getChild(i)->getStationary() == Stationary::BETWEEN_VIEWS ||
getChild(i)->getStationary() == Stationary::ALWAYS)) {
childStationary = true;
}
}
if (childStationary) {
if (viewState.getSystem() != mRoot->getSystem())
continue;
mRenderer->popClipRect();
getChild(i)->render(mRenderer->getIdentity());
clipRectFunc();
}
else {
getChild(i)->render(trans);
}
}
renderChildren(trans);
mRenderer->popClipRect();
}
@ -423,7 +488,7 @@ std::vector<HelpPrompt> GamelistView::getHelpPrompts()
}
if (mRoot->getSystem()->getThemeFolder() == "custom-collections" && mCursorStack.empty() &&
ViewController::getInstance()->getState().viewing == ViewController::GAMELIST)
ViewController::getInstance()->getState().viewing == ViewController::ViewMode::GAMELIST)
prompts.push_back(HelpPrompt("a", "select"));
else
prompts.push_back(HelpPrompt("a", "select"));
@ -440,7 +505,7 @@ std::vector<HelpPrompt> GamelistView::getHelpPrompts()
if (mRoot->getSystem()->getThemeFolder() == "custom-collections" &&
!CollectionSystemsManager::getInstance()->isEditing() && mCursorStack.empty() &&
ViewController::getInstance()->getState().viewing == ViewController::GAMELIST) {
ViewController::getInstance()->getState().viewing == ViewController::ViewMode::GAMELIST) {
prompts.push_back(HelpPrompt("y", "jump to game"));
}
else if (mRoot->getSystem()->isGameSystem() &&

View file

@ -1395,12 +1395,38 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary)
int renderBefore {static_cast<int>(mCamOffset)};
int renderAfter {static_cast<int>(mCamOffset)};
// If we're transitioning then also render the previous and next systems.
if (isAnimationPlaying(0)) {
const ViewController::State viewState {ViewController::getInstance()->getState()};
// If we're transitioning between systems, then also render the previous and next systems.
if (isAnimationPlaying(0) && viewState.viewing == ViewController::ViewMode::SYSTEM_SELECT) {
renderBefore -= 1;
renderAfter += 1;
}
bool stationaryApplicable {false};
// If it's the startup animation, then don't apply stationary properties.
if (viewState.previouslyViewed == ViewController::ViewMode::NOTHING)
stationaryApplicable = false;
// If it's a system to system transition and these animations are set to slide.
if (static_cast<ViewTransitionAnimation>(Settings::getInstance()->getInt(
"TransitionsSystemToSystem")) == ViewTransitionAnimation::SLIDE &&
isAnimationPlaying(0))
stationaryApplicable = true;
// If it's a system to gamelist transition and these animations are set to slide.
if (static_cast<ViewTransitionAnimation>(Settings::getInstance()->getInt(
"TransitionsSystemToGamelist")) == ViewTransitionAnimation::SLIDE &&
viewState.viewing == ViewController::ViewMode::GAMELIST)
stationaryApplicable = true;
// If it's a gamelist to system transition and these animations are set to slide.
if (static_cast<ViewTransitionAnimation>(Settings::getInstance()->getInt(
"TransitionsGamelistToSystem")) == ViewTransitionAnimation::SLIDE &&
viewState.previouslyViewed == ViewController::ViewMode::GAMELIST)
stationaryApplicable = true;
for (int i {renderBefore}; i <= renderAfter; ++i) {
int index {i};
while (index < 0)
@ -1432,13 +1458,46 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary)
elementTrans, glm::round(glm::vec3 {0.0f, (i - mCamOffset) * mSize.y, 0.0f}));
}
mRenderer->pushClipRect(
glm::ivec2 {static_cast<int>(glm::round(elementTrans[3].x)),
static_cast<int>(glm::round(elementTrans[3].y))},
glm::ivec2 {static_cast<int>(mSize.x), static_cast<int>(mSize.y)});
auto clipRectFunc = [this, elementTrans]() {
mRenderer->pushClipRect(
glm::ivec2 {static_cast<int>(glm::round(elementTrans[3].x)),
static_cast<int>(glm::round(elementTrans[3].y))},
glm::ivec2 {static_cast<int>(mSize.x), static_cast<int>(mSize.y)});
};
clipRectFunc();
if (mSystemElements.size() > static_cast<size_t>(index)) {
for (auto child : mSystemElements[index].children) {
bool renderChild {true};
bool childStationary {false};
if (stationaryApplicable) {
if (child->getStationary() == Stationary::NEVER) {
childStationary = false;
}
else if ((child->getStationary() == Stationary::WITHIN_VIEW ||
child->getStationary() == Stationary::ALWAYS) &&
isAnimationPlaying(0)) {
childStationary = true;
if (index != static_cast<int>(std::round(mCamOffset))) {
if (mCamOffset <= mSystemElements.size() - 1)
renderChild = false;
if (mCamOffset > static_cast<float>(mSystemElements.size() - 1) &&
index != 0)
renderChild = false;
if (mCamOffset <
static_cast<float>(mSystemElements.size()) - 0.5f &&
index == 0)
renderChild = false;
}
}
else if ((child->getStationary() == Stationary::BETWEEN_VIEWS ||
child->getStationary() == Stationary::ALWAYS) &&
!isAnimationPlaying(0)) {
childStationary = true;
}
}
if (abovePrimary && (child->getZIndex() > primaryZIndex)) {
if (mFadeTransitions && mPrimary->getFadeAbovePrimary()) {
if (mFadeTransitions || child->getOpacity() != 1.0f)
@ -1447,13 +1506,30 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary)
else {
child->setOpacity(1.0f);
}
child->render(elementTrans);
if (renderChild) {
if (childStationary) {
mRenderer->popClipRect();
child->render(mRenderer->getIdentity());
clipRectFunc();
}
else {
child->render(elementTrans);
}
}
}
else if (!abovePrimary && child->getZIndex() <= primaryZIndex) {
if (mFadeTransitions || child->getDimming() != 1.0f)
child->setDimming(1.0f - mFadeOpacity);
child->render(elementTrans);
if (renderChild) {
if (childStationary) {
mRenderer->popClipRect();
child->render(mRenderer->getIdentity());
clipRectFunc();
}
else {
child->render(elementTrans);
}
}
}
}
}

View file

@ -50,7 +50,8 @@ ViewController::ViewController() noexcept
, mLockInput {false}
, mNextSystem {false}
{
mState.viewing = NOTHING;
mState.viewing = ViewMode::NOTHING;
mState.previouslyViewed = ViewMode::NOTHING;
}
ViewController* ViewController::getInstance()
@ -410,7 +411,7 @@ void ViewController::ReloadAndGoToStart()
{
mWindow->renderSplashScreen(Window::SplashScreenState::RELOADING, 0.0f);
reloadAll();
if (mState.viewing == GAMELIST) {
if (mState.viewing == ViewMode::GAMELIST) {
goToSystemView(SystemData::sSystemVector.front(), false);
goToSystem(SystemData::sSystemVector.front(), false);
}
@ -488,7 +489,7 @@ void ViewController::goToSystemView(SystemData* system, bool playTransition)
{
bool applicationStartup {false};
if (mState.viewing == NOTHING)
if (mState.viewing == ViewMode::NOTHING)
applicationStartup = true;
// Restore the X position for the view, if it was previously moved.
@ -508,7 +509,8 @@ void ViewController::goToSystemView(SystemData* system, bool playTransition)
if (system->isGroupedCustomCollection())
system = system->getRootFolder()->getParent()->getSystem();
mState.viewing = SYSTEM_SELECT;
mState.previouslyViewed = mState.viewing;
mState.viewing = ViewMode::SYSTEM_SELECT;
mState.system = system;
mSystemViewTransition = true;
@ -577,7 +579,7 @@ void ViewController::goToSystem(SystemData* system, bool animate)
void ViewController::goToNextGamelist()
{
assert(mState.viewing == GAMELIST);
assert(mState.viewing == ViewMode::GAMELIST);
SystemData* system {getState().getSystem()};
assert(system);
NavigationSounds::getInstance().playThemeNavigationSound(QUICKSYSSELECTSOUND);
@ -587,7 +589,7 @@ void ViewController::goToNextGamelist()
void ViewController::goToPrevGamelist()
{
assert(mState.viewing == GAMELIST);
assert(mState.viewing == ViewMode::GAMELIST);
SystemData* system {getState().getSystem()};
assert(system);
NavigationSounds::getInstance().playThemeNavigationSound(QUICKSYSSELECTSOUND);
@ -608,12 +610,12 @@ void ViewController::goToGamelist(SystemData* system)
ViewTransition transitionType;
ViewTransitionAnimation transitionAnim;
if (mState.viewing == SYSTEM_SELECT) {
if (mState.viewing == ViewMode::SYSTEM_SELECT) {
transitionType = ViewTransition::SYSTEM_TO_GAMELIST;
transitionAnim = static_cast<ViewTransitionAnimation>(
Settings::getInstance()->getInt("TransitionsSystemToGamelist"));
}
else if (mState.viewing == NOTHING) {
else if (mState.viewing == ViewMode::NOTHING) {
transitionType = ViewTransition::STARTUP_TO_GAMELIST;
transitionAnim = static_cast<ViewTransitionAnimation>(
Settings::getInstance()->getInt("TransitionsStartupToGamelist"));
@ -642,13 +644,13 @@ void ViewController::goToGamelist(SystemData* system)
mPreviousView.reset();
mPreviousView = nullptr;
}
else if (!mPreviousView && mState.viewing == GAMELIST) {
else if (!mPreviousView && mState.viewing == ViewMode::GAMELIST) {
// This is needed as otherwise the static image would not get rendered during the
// first Slide transition when coming from the System view.
mSkipView = getGamelistView(system);
}
if (mState.viewing != SYSTEM_SELECT) {
if (mState.viewing != ViewMode::SYSTEM_SELECT) {
mPreviousView = mCurrentView;
mSystemViewTransition = false;
}
@ -659,7 +661,8 @@ void ViewController::goToGamelist(SystemData* system)
// Find if we're wrapping around the first and last systems, which requires the gamelist
// to be moved in order to avoid weird camera movements. This is only needed for the
// slide transition style.
if (mState.viewing == GAMELIST && SystemData::sSystemVector.size() > 1 && slideTransitions) {
if (mState.viewing == ViewMode::GAMELIST && SystemData::sSystemVector.size() > 1 &&
slideTransitions) {
if (SystemData::sSystemVector.front() == mState.getSystem()) {
if (SystemData::sSystemVector.back() == system)
wrapFirstToLast = true;
@ -671,7 +674,7 @@ void ViewController::goToGamelist(SystemData* system)
}
// Stop any scrolling, animations and camera movements.
if (mState.viewing == SYSTEM_SELECT) {
if (mState.viewing == ViewMode::SYSTEM_SELECT) {
mSystemListView->stopScrolling();
if (mSystemListView->isSystemAnimationPlaying(0))
mSystemListView->finishSystemAnimation(0);
@ -681,7 +684,7 @@ void ViewController::goToGamelist(SystemData* system)
(!fadeTransitions && mLastTransitionAnim == ViewTransitionAnimation::FADE))
cancelViewTransitions();
if (mState.viewing == SYSTEM_SELECT) {
if (mState.viewing == ViewMode::SYSTEM_SELECT) {
// Move the system list.
auto sysList = getSystemListView();
float offsetX {sysList->getPosition().x};
@ -728,7 +731,7 @@ void ViewController::goToGamelist(SystemData* system)
mCurrentView->finishAnimation(0);
// Application startup animation, if starting in a gamelist rather than in the system view.
if (mState.viewing == NOTHING) {
if (mState.viewing == ViewMode::NOTHING) {
if (mLastTransitionAnim == ViewTransitionAnimation::FADE)
cancelViewTransitions();
mCamera = glm::translate(mCamera, glm::round(-mCurrentView->getPosition()));
@ -744,7 +747,8 @@ void ViewController::goToGamelist(SystemData* system)
}
}
mState.viewing = GAMELIST;
mState.previouslyViewed = mState.viewing;
mState.viewing = ViewMode::GAMELIST;
mState.system = system;
if (mCurrentView)
@ -1157,9 +1161,9 @@ void ViewController::render(const glm::mat4& parentTrans)
glm::mat4 transInverse {glm::inverse(trans)};
// Camera position, position + size.
glm::vec3 viewStart {transInverse[3]};
glm::vec3 viewEnd {std::fabs(trans[3].x) + Renderer::getScreenWidth(),
std::fabs(trans[3].y) + Renderer::getScreenHeight(), 0.0f};
const glm::vec3 viewStart {transInverse[3]};
const glm::vec3 viewEnd {std::fabs(trans[3].x) + Renderer::getScreenWidth(),
std::fabs(trans[3].y) + Renderer::getScreenHeight(), 0.0f};
// Keep track of UI mode changes.
UIModeController::getInstance()->monitorUIMode();
@ -1169,19 +1173,27 @@ void ViewController::render(const glm::mat4& parentTrans)
if (mSystemListView == mCurrentView || (mSystemViewTransition && isCameraMoving()))
getSystemListView()->render(trans);
// Draw the gamelists.
for (auto it = mGamelistViews.cbegin(); it != mGamelistViews.cend(); ++it) {
// Same thing as for the system view, limit the rendering only to what needs to be drawn.
if (it->second == mCurrentView || (it->second == mPreviousView && isCameraMoving())) {
// Clipping.
glm::vec3 guiStart {it->second->getPosition()};
glm::vec3 guiEnd {it->second->getPosition() +
glm::vec3 {it->second->getSize().x, it->second->getSize().y, 0.0f}};
auto gamelistRenderFunc = [this, trans, viewStart, viewEnd](auto it) {
const glm::vec3 guiStart {it->second->getPosition()};
const glm::vec3 guiEnd {it->second->getPosition() +
glm::vec3 {it->second->getSize().x, it->second->getSize().y, 0.0f}};
if (guiEnd.x >= viewStart.x && guiEnd.y >= viewStart.y && guiStart.x <= viewEnd.x &&
guiStart.y <= viewEnd.y)
it->second->render(trans);
};
if (guiEnd.x >= viewStart.x && guiEnd.y >= viewStart.y && guiStart.x <= viewEnd.x &&
guiStart.y <= viewEnd.y)
it->second->render(trans);
}
// Draw the gamelists. In the same manner as for the system view, limit the rendering only
// to what needs to be drawn.
for (auto it = mGamelistViews.cbegin(); it != mGamelistViews.cend(); ++it) {
if (it->second == mPreviousView && isCameraMoving())
gamelistRenderFunc(it);
}
// Always render the currently selected system last so that any stationary elements will get
// correctly rendered on top.
for (auto it = mGamelistViews.cbegin(); it != mGamelistViews.cend(); ++it) {
if (it->second == mCurrentView)
gamelistRenderFunc(it);
}
if (mWindow->peekGui() == this)
@ -1364,10 +1376,10 @@ void ViewController::reloadAll()
}
// Update mCurrentView since the pointers changed.
if (mState.viewing == GAMELIST) {
if (mState.viewing == ViewMode::GAMELIST) {
mCurrentView = getGamelistView(mState.getSystem());
}
else if (mState.viewing == SYSTEM_SELECT) {
else if (mState.viewing == ViewMode::SYSTEM_SELECT) {
SystemData* system {mState.getSystem()};
mSystemListView->goToSystem(system, false);
mCurrentView = mSystemListView;

View file

@ -98,19 +98,19 @@ public:
void update(int deltaTime) override;
void render(const glm::mat4& parentTrans) override;
enum ViewMode {
enum class ViewMode {
NOTHING,
START_SCREEN,
SYSTEM_SELECT,
GAMELIST
};
struct State {
ViewMode viewing;
ViewMode previouslyViewed;
SystemData* getSystem() const
{
assert(viewing == GAMELIST || viewing == SYSTEM_SELECT);
assert(viewing == ViewMode::GAMELIST || viewing == ViewMode::SYSTEM_SELECT);
return system;
}

View file

@ -30,6 +30,7 @@ GuiComponent::GuiComponent()
, mOrigin {0.0f, 0.0f}
, mRotationOrigin {0.5f, 0.5f}
, mSize {0.0f, 0.0f}
, mStationary {Stationary::NEVER}
, mBrightness {0.0f}
, mOpacity {1.0f}
, mSaturation {1.0f}
@ -45,7 +46,7 @@ GuiComponent::GuiComponent()
, mEnabled {true}
, mTransform {Renderer::getIdentity()}
{
for (unsigned char i = 0; i < MAX_ANIMATIONS; ++i)
for (unsigned char i {0}; i < MAX_ANIMATIONS; ++i)
mAnimationMap[i] = nullptr;
}
@ -58,7 +59,7 @@ GuiComponent::~GuiComponent()
if (mParent)
mParent->removeChild(this);
for (unsigned int i = 0; i < getChildCount(); ++i)
for (unsigned int i {0}; i < getChildCount(); ++i)
getChild(i)->setParent(nullptr);
}
@ -70,7 +71,7 @@ void GuiComponent::textInput(const std::string& text, const bool pasting)
bool GuiComponent::input(InputConfig* config, Input input)
{
for (unsigned int i = 0; i < getChildCount(); ++i) {
for (unsigned int i {0}; i < getChildCount(); ++i) {
if (getChild(i)->input(config, input))
return true;
}
@ -147,7 +148,7 @@ void GuiComponent::removeChild(GuiComponent* cmp)
cmp->setParent(nullptr);
for (auto i = mChildren.cbegin(); i != mChildren.cend(); ++i) {
for (auto i {mChildren.cbegin()}; i != mChildren.cend(); ++i) {
if (*i == cmp) {
mChildren.erase(i);
return;
@ -252,13 +253,13 @@ const bool GuiComponent::advanceAnimation(unsigned char slot, unsigned int time)
void GuiComponent::stopAllAnimations()
{
for (unsigned char i = 0; i < MAX_ANIMATIONS; ++i)
for (unsigned char i {0}; i < MAX_ANIMATIONS; ++i)
stopAnimation(i);
}
void GuiComponent::cancelAllAnimations()
{
for (unsigned char i = 0; i < MAX_ANIMATIONS; ++i)
for (unsigned char i {0}; i < MAX_ANIMATIONS; ++i)
cancelAnimation(i);
}
@ -327,13 +328,13 @@ const glm::mat4& GuiComponent::getTransform()
void GuiComponent::onShow()
{
for (unsigned int i = 0; i < getChildCount(); ++i)
for (unsigned int i {0}; i < getChildCount(); ++i)
getChild(i)->onShow();
}
void GuiComponent::onHide()
{
for (unsigned int i = 0; i < getChildCount(); ++i)
for (unsigned int i {0}; i < getChildCount(); ++i)
getChild(i)->onHide();
}
@ -413,18 +414,18 @@ void GuiComponent::updateHelpPrompts()
void GuiComponent::updateSelf(int deltaTime)
{
for (unsigned char i = 0; i < MAX_ANIMATIONS; ++i)
for (unsigned char i {0}; i < MAX_ANIMATIONS; ++i)
advanceAnimation(i, deltaTime);
}
void GuiComponent::updateChildren(int deltaTime)
{
for (unsigned int i = 0; i < getChildCount(); ++i)
for (unsigned int i {0}; i < getChildCount(); ++i)
getChild(i)->update(deltaTime);
}
void GuiComponent::renderChildren(const glm::mat4& transform) const
{
for (unsigned int i = 0; i < getChildCount(); ++i)
for (unsigned int i {0}; i < getChildCount(); ++i)
getChild(i)->render(transform);
}

View file

@ -57,6 +57,13 @@ enum class LetterCase {
UNDEFINED
};
enum class Stationary {
NEVER,
ALWAYS,
WITHIN_VIEW,
BETWEEN_VIEWS
};
class GuiComponent
{
public:
@ -109,6 +116,8 @@ public:
}
void setRotationOrigin(glm::vec2 origin) { setRotationOrigin(origin.x, origin.y); }
const Stationary getStationary() const { return mStationary; }
virtual glm::vec2 getSize() const { return mSize; }
void setSize(const glm::vec2& size) { setSize(size.x, size.y); }
void setSize(const float w, const float h);
@ -388,6 +397,7 @@ protected:
glm::vec2 mOrigin;
glm::vec2 mRotationOrigin;
glm::vec2 mSize;
Stationary mStationary;
float mBrightness;
float mOpacity;

View file

@ -254,6 +254,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"origin", NORMALIZED_PAIR},
{"rotation", FLOAT},
{"rotationOrigin", NORMALIZED_PAIR},
{"stationary", STRING},
{"flipHorizontal", BOOLEAN},
{"flipVertical", BOOLEAN},
{"path", PATH},
@ -283,6 +284,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"cropSize", NORMALIZED_PAIR},
{"maxSize", NORMALIZED_PAIR},
{"origin", NORMALIZED_PAIR},
{"stationary", STRING},
{"path", PATH},
{"default", PATH},
{"defaultImage", PATH},
@ -313,6 +315,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"origin", NORMALIZED_PAIR},
{"rotation", FLOAT},
{"rotationOrigin", NORMALIZED_PAIR},
{"stationary", STRING},
{"metadataElement", BOOLEAN},
{"path", PATH},
{"speed", FLOAT},
@ -333,6 +336,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"origin", NORMALIZED_PAIR},
{"rotation", FLOAT},
{"rotationOrigin", NORMALIZED_PAIR},
{"stationary", STRING},
{"horizontalAlignment", STRING},
{"direction", STRING},
{"lines", UNSIGNED_INTEGER},
@ -364,6 +368,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"origin", NORMALIZED_PAIR},
{"rotation", FLOAT},
{"rotationOrigin", NORMALIZED_PAIR},
{"stationary", STRING},
{"text", STRING},
{"systemdata", STRING},
{"metadata", STRING},
@ -395,6 +400,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"origin", NORMALIZED_PAIR},
{"rotation", FLOAT},
{"rotationOrigin", NORMALIZED_PAIR},
{"stationary", STRING},
{"metadata", STRING},
{"defaultValue", STRING},
{"gameselector", STRING},
@ -418,6 +424,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"origin", NORMALIZED_PAIR},
{"rotation", FLOAT},
{"rotationOrigin", NORMALIZED_PAIR},
{"stationary", STRING},
{"fontPath", PATH},
{"fontSize", FLOAT},
{"horizontalAlignment", STRING},
@ -433,6 +440,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"origin", NORMALIZED_PAIR},
{"rotation", FLOAT},
{"rotationOrigin", NORMALIZED_PAIR},
{"stationary", STRING},
{"gameselector", STRING},
{"gameselectorEntry", UNSIGNED_INTEGER},
{"interpolation", STRING},

View file

@ -215,6 +215,22 @@ void BadgeComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (!elem)
return;
if (properties & ThemeFlags::POSITION && elem->has("stationary")) {
const std::string& stationary {elem->get<std::string>("stationary")};
if (stationary == "never")
mStationary = Stationary::NEVER;
else if (stationary == "always")
mStationary = Stationary::ALWAYS;
else if (stationary == "withinView")
mStationary = Stationary::WITHIN_VIEW;
else if (stationary == "betweenViews")
mStationary = Stationary::BETWEEN_VIEWS;
else
LOG(LogWarning) << "BadgeComponent: Invalid theme configuration, property "
"\"stationary\" for element \""
<< element.substr(7) << "\" defined as \"" << stationary << "\"";
}
if (elem->has("horizontalAlignment")) {
const std::string horizontalAlignment {elem->get<std::string>("horizontalAlignment")};
if (horizontalAlignment != "left" && horizontalAlignment != "center" &&

View file

@ -125,6 +125,22 @@ void DateTimeComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (!elem)
return;
if (properties & ThemeFlags::POSITION && elem->has("stationary")) {
const std::string& stationary {elem->get<std::string>("stationary")};
if (stationary == "never")
mStationary = Stationary::NEVER;
else if (stationary == "always")
mStationary = Stationary::ALWAYS;
else if (stationary == "withinView")
mStationary = Stationary::WITHIN_VIEW;
else if (stationary == "betweenViews")
mStationary = Stationary::BETWEEN_VIEWS;
else
LOG(LogWarning) << "DateTimeComponent: Invalid theme configuration, property "
"\"stationary\" for element \""
<< element.substr(9) << "\" defined as \"" << stationary << "\"";
}
if (elem->has("format"))
setFormat(elem->get<std::string>("format"));
@ -147,8 +163,9 @@ void DateTimeComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
setHorizontalAlignment(ALIGN_RIGHT);
else
LOG(LogWarning) << "DateTimeComponent: Invalid theme configuration, property "
"<horizontalAlignment> defined as \""
<< horizontalAlignment << "\"";
"\"horizontalAlignment\" for element \""
<< element.substr(9) << "\" defined as \"" << horizontalAlignment
<< "\"";
}
if (properties & ALIGNMENT && elem->has("verticalAlignment")) {
@ -161,8 +178,8 @@ void DateTimeComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
setVerticalAlignment(ALIGN_BOTTOM);
else
LOG(LogWarning) << "DateTimeComponent: Invalid theme configuration, property "
"<verticalAlignment> defined as \""
<< verticalAlignment << "\"";
"\"verticalAlignment\" for element \""
<< element.substr(9) << "\" defined as \"" << verticalAlignment << "\"";
}
if (properties & METADATA && elem->has("metadata")) {
@ -179,9 +196,9 @@ void DateTimeComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
mThemeMetadata = metadata;
}
else {
LOG(LogError) << "DateTimeComponent: Invalid theme configuration, property "
"<metadata> defined as \""
<< metadata << "\"";
LOG(LogWarning) << "DateTimeComponent: Invalid theme configuration, property "
"\"metadata\" for element \""
<< element.substr(9) << "\" defined as \"" << metadata << "\"";
}
}
@ -204,8 +221,8 @@ void DateTimeComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
}
else if (letterCase != "none") {
LOG(LogWarning) << "DateTimeComponent: Invalid theme configuration, property "
"<letterCase> defined as \""
<< letterCase << "\"";
"\"letterCase\" for element \""
<< element.substr(9) << "\" defined as \"" << letterCase << "\"";
}
}

View file

@ -317,6 +317,22 @@ void GIFAnimComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
mTargetSize = mSize;
}
if (properties & ThemeFlags::POSITION && elem->has("stationary")) {
const std::string& stationary {elem->get<std::string>("stationary")};
if (stationary == "never")
mStationary = Stationary::NEVER;
else if (stationary == "always")
mStationary = Stationary::ALWAYS;
else if (stationary == "withinView")
mStationary = Stationary::WITHIN_VIEW;
else if (stationary == "betweenViews")
mStationary = Stationary::BETWEEN_VIEWS;
else
LOG(LogWarning) << "GIFAnimComponent: Invalid theme configuration, property "
"\"stationary\" for element \""
<< element.substr(10) << "\" defined as \"" << stationary << "\"";
}
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;

View file

@ -503,6 +503,22 @@ void ImageComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
}
}
if (properties & ThemeFlags::POSITION && elem->has("stationary")) {
const std::string& stationary {elem->get<std::string>("stationary")};
if (stationary == "never")
mStationary = Stationary::NEVER;
else if (stationary == "always")
mStationary = Stationary::ALWAYS;
else if (stationary == "withinView")
mStationary = Stationary::WITHIN_VIEW;
else if (stationary == "betweenViews")
mStationary = Stationary::BETWEEN_VIEWS;
else
LOG(LogWarning) << "ImageComponent: Invalid theme configuration, property "
"\"stationary\" for element \""
<< element.substr(6) << "\" defined as \"" << stationary << "\"";
}
if (elem->has("interpolation")) {
const std::string& interpolation {elem->get<std::string>("interpolation")};
if (interpolation == "linear") {

View file

@ -287,6 +287,22 @@ void LottieAnimComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
mTargetSize = mSize;
}
if (properties & ThemeFlags::POSITION && elem->has("stationary")) {
const std::string& stationary {elem->get<std::string>("stationary")};
if (stationary == "never")
mStationary = Stationary::NEVER;
else if (stationary == "always")
mStationary = Stationary::ALWAYS;
else if (stationary == "withinView")
mStationary = Stationary::WITHIN_VIEW;
else if (stationary == "betweenViews")
mStationary = Stationary::BETWEEN_VIEWS;
else
LOG(LogWarning) << "LottieAnimComponent: Invalid theme configuration, property "
"\"stationary\" for element \""
<< element.substr(10) << "\" defined as \"" << stationary << "\"";
}
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;

View file

@ -211,6 +211,22 @@ void RatingComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
mSize.x = std::round(mSize.y * mImageRatio) * NUM_RATING_STARS;
}
if (properties & ThemeFlags::POSITION && elem->has("stationary")) {
const std::string& stationary {elem->get<std::string>("stationary")};
if (stationary == "never")
mStationary = Stationary::NEVER;
else if (stationary == "always")
mStationary = Stationary::ALWAYS;
else if (stationary == "withinView")
mStationary = Stationary::WITHIN_VIEW;
else if (stationary == "betweenViews")
mStationary = Stationary::BETWEEN_VIEWS;
else
LOG(LogWarning) << "RatingComponent: Invalid theme configuration, property "
"\"stationary\" for element \""
<< element.substr(7) << "\" defined as \"" << stationary << "\"";
}
bool linearInterpolation {false};
if (elem->has("interpolation")) {

View file

@ -374,6 +374,23 @@ void TextComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
if (!elem)
return;
if (properties & ThemeFlags::POSITION && elem->has("stationary")) {
const std::string& stationary {elem->get<std::string>("stationary")};
if (stationary == "never")
mStationary = Stationary::NEVER;
else if (stationary == "always")
mStationary = Stationary::ALWAYS;
else if (stationary == "withinView")
mStationary = Stationary::WITHIN_VIEW;
else if (stationary == "betweenViews")
mStationary = Stationary::BETWEEN_VIEWS;
else
LOG(LogWarning) << componentName
<< ": Invalid theme configuration, property "
"\"stationary\" for element \""
<< element.substr(5) << "\" defined as \"" << stationary << "\"";
}
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;

View file

@ -167,6 +167,22 @@ void VideoComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
mVideoAreaPos = elem->get<glm::vec2>("pos") * scale;
}
if (properties & ThemeFlags::POSITION && elem->has("stationary")) {
const std::string& stationary {elem->get<std::string>("stationary")};
if (stationary == "never")
mStationary = Stationary::NEVER;
else if (stationary == "always")
mStationary = Stationary::ALWAYS;
else if (stationary == "withinView")
mStationary = Stationary::WITHIN_VIEW;
else if (stationary == "betweenViews")
mStationary = Stationary::BETWEEN_VIEWS;
else
LOG(LogWarning) << "VideoComponent: Invalid theme configuration, property "
"\"stationary\" for element \""
<< element.substr(6) << "\" defined as \"" << stationary << "\"";
}
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;